Copyright © 2025 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
Gamepad 명세는 게임패드 장치를 나타내는 저수준 인터페이스를 정의합니다.
이 절은 이 문서가 발행된 시점의 상태를 설명합니다. 현재 W3C 발행물 목록과 이 기술 보고서의 최신 개정본은 W3C 표준 및 초안 색인에서 찾을 수 있습니다.
이 문서는 진행 중인 작업입니다.
이 문서는 웹 애플리케이션 워킹 그룹이 권고안 트랙을 사용하여 작업 초안으로 발행했습니다.
작업 초안으로 발행되었다고 해서 W3C와 그 회원의 승인을 의미하지는 않습니다.
이 문서는 초안 문서이며 언제든지 다른 문서로 갱신, 대체 또는 폐기될 수 있습니다. 진행 중인 작업 외의 용도로 이 문서를 인용하는 것은 부적절합니다.
이 문서는 W3C 특허 정책에 따라 운영되는 그룹에서 작성했습니다. W3C는 해당 그룹의 산출물과 관련하여 이루어진 모든 특허 공개의 공개 목록을 유지합니다; 그 페이지에는 특허를 공개하는 방법에 대한 지침도 포함되어 있습니다. 본인이 필수 청구항을 포함한다고 믿는 특허를 실제로 알고 있는 개인은 W3C 특허 정책 6절에 따라 그 정보를 공개해야 합니다.
이 문서는 2023년 11월 03일 W3C 프로세스 문서의 적용을 받습니다.
이 절은 비규범적입니다.
일부 사용자 에이전트에는 연결된 게임패드 장치가 있습니다. 이러한 장치는 게임 애플리케이션의 입력과 "10 foot" 사용자 인터페이스(프레젠테이션, 미디어 뷰어)에 적합하며 바람직합니다.
현재 게임패드를 입력으로 사용하는 유일한 방법은 마우스 또는 키보드 이벤트를 에뮬레이트하는 것이지만, 이는 정보를 잃게 하며 에뮬레이션을 수행하기 위해 사용자 에이전트 외부의 추가 소프트웨어를 필요로 합니다.
한편, 네이티브 애플리케이션은 시스템 API를 통해 이러한 장치에 접근할 수 있습니다.
Gamepad API는 웹 애플리케이션이 게임패드 데이터에 직접 동작할 수 있게 하는 인터페이스를 명시함으로써 이 문제에 대한 해결책을 제공합니다.
게임을 제어하도록 설계된 외부 장치와 인터페이스하는 것은 완전한 일반성으로 접근할 경우 매우 크고 다루기 어려워질 가능성이 있습니다. 이 명세에서는 널리 구현될 수 있고 폭넓게 유용한 기능의 유용한 부분 집합을 제공하기 위해 범위를 명시적으로 좁히기로 선택합니다.
구체적으로, 우리는 게임패드를 지원하는 데 필요한 기능만 지원하기로 선택합니다. 게임패드를 지원하려면 두 가지 입력 유형, 즉 버튼과 축이 필요합니다. 버튼과 축은 모두 아날로그 값으로 보고되며, 버튼은 [0 .. 1] 범위이고, 축은 [-1 .. 1] 범위입니다.
주요 목표는 게임패드 장치를 지원하는 것이지만, 이러한 두 가지 유형의 아날로그 입력을 지원하면 현재 게임 시스템에서 흔히 쓰이는 조이스틱, 운전대, 페달, 가속도계 등 다른 유사한 장치도 지원할 수 있습니다. 따라서 "gamepad"라는 이름은 이 명세가 다루는 전체 장치 집합의 일반적인 이름이 되려는 것이 아니라 예시적인 이름입니다.
우리는 일부 게임 맥락에서도 사용될 수 있는 더 복잡한 장치, 즉 모션 감지, 깊이 감지, 비디오 분석, 제스처 인식 등을 수행하는 장치에 대한 지원은 명시적으로 제외합니다.
게임패드는 입력 컨트롤과 출력 컨트롤의 모음입니다. 입력 컨트롤에는 시간이 지남에 따라 갱신될 수 있는 입력 값 모음이 있습니다. 입력 컨트롤에는 게임패드의 버튼, 트리거, 조이스틱, 엄지스틱, 터치 표면이 포함됩니다. 출력 컨트롤은 게임패드와 상호작용하는 사용자에게 피드백을 제공하기 위해 게임패드의 동작을 변경하는 기능입니다. 출력 컨트롤에는 게임패드의 햅틱 액추에이터가 포함됩니다. 게임패드는 사용자 에이전트가 그 입력 컨트롤의 현재 상태를 읽을 수 있으면 사용 가능합니다. 게임패드가 사용 가능하지 않으면 사용 불가합니다. 게임패드가 사용 가능한 동안에는 그 입력 컨트롤과 출력 컨트롤이 변경될 수 없습니다.
사용자 에이전트는 다음을 담당합니다:
게임패드에는 게임패드 식별자 문자열이 있습니다. 이는 게임패드의 브랜드나 스타일을 식별하는 사람이 읽을 수 있는 문자열입니다. 그 내용은 사용자 에이전트가 결정합니다.
게임패드에는 입력 컨트롤 각각의 위치, 방향, 유형을 설명하는 입력 컨트롤 배치가 있을 수 있습니다. 사용자 에이전트는 게임패드가 표준 배치와 대응하는 시점을 인식할 책임이 있습니다. 이는 게임패드가 같은 표준 배치와 대응하는 다른 게임패드와 상호 교환하여 사용할 수 있게 하는 입력 컨트롤 배치를 갖는다는 뜻입니다. 사용자 에이전트는 그 입력 컨트롤이 표준 배치에 설명된 입력 컨트롤과 거의 같은 상대적 위치와 방향을 가지면, 그 배치가 표준 배치와 대응한다고 간주하는 것이 좋습니다.
사용자 에이전트는 보통 게임패드의 입력 컨트롤 배치를 직접 검사할 수 없으며, 배치를 결정하기 위해 휴리스틱을 사용할 수 있습니다. 사용자 에이전트는 게임패드가 표준 배치와 대응하는지 결정할 때 장치 식별자를 고려하는 것이 좋습니다. 시스템이 각 입력 컨트롤에 레이블을 할당하고 그 레이블이 특정 배치를 암시한다면, 사용자 에이전트는 그 게임패드가 그 배치를 가진다고 간주하는 것이 좋습니다. 같은 입력 컨트롤을 가진 표준 모델과 접근성 모델이 있을 때, 사용자 에이전트는 접근성 모델이 표준 모델과 같은 입력 컨트롤 배치를 가진다고 간주하는 것이 좋습니다.
각 입력 컨트롤에는 연결된 입력 값이 하나 이상 있으며, 이는 컨트롤의 현재 상태를 나타내는 숫자 값입니다. 입력 값은 언제든 갱신될 수 있습니다. 사용자 에이전트는 입력 값이 갱신된 시점을 감지할 책임이 있으며, 갱신과 갱신된 값이 읽히는 시점 사이의 지연을 최소화하려고 노력하는 것이 좋습니다.
입력 값을 읽으면 그 논리 값, 즉 현재 상태의 비스케일 숫자 표현이 반환됩니다. 입력 값에는 또한 경계 내 논리 값의 최솟값과 최댓값을 정의하는 논리 최솟값과 논리 최댓값이 있습니다.
입력 값에는 입력 값이 나타내는 데이터의 유형을 식별하는 32비트 값인 HID 사용 식별자가 연결될 수 있습니다. HID 사용은 입력 컨트롤 배치를 정확히 설명하지는 않지만, 관례상 유사한 배치를 가진 많은 게임패드는 유사한 사용을 사용합니다. 사용자 에이전트는 입력 컨트롤 배치를 결정할 때 HID 사용 식별자에 관한 관례에 의존하는 것이 좋습니다.
게임패드에는 축 입력이 있을 수 있습니다. 축은 기준 위치로부터 컨트롤의 현재 변위를 나타내는 입력 값입니다.
게임패드에는 축 목록이 있으며, 이는 목록으로서 사용자 에이전트가 결정한 어떤 순서로 게임패드에 대한 모든 축 입력을 포함합니다.
입력 컨트롤은 사용자가 입력 컨트롤과 상호작용을 멈추면 축이 자동으로 중앙 위치로 돌아가도록 설계될 수 있습니다. 그렇다면 그 축에는 선호 축 상태가 있습니다. 선호 축 상태가 있는 축에는 추가 입력 값, 즉 중앙 위치 값도 있을 수 있습니다. 이는 축이 중앙에 있을 때의 논리 값입니다.
게임패드에는 터치 표면이 있을 수 있습니다. 터치 표면은 접촉 지점을 나타내는 2D 위치 데이터를 제공하는 입력 컨트롤입니다. 게임패드에는 터치 표면 목록이 있으며, 이는 목록으로서 게임패드의 터치 표면을 포함합니다. 이 목록은 게임패드의 왼쪽에 더 가까운 터치 표면이 목록의 시작 부분에 더 가깝게 나타나도록 정렬됩니다.
터치 표면에는 활성 터치 지점 목록 입력 값이 있습니다. 이는 센서가 현재 감지한 접촉 지점을 나타내는 0개 이상의 터치 지점의 목록입니다. 터치 지점은 단일 시점의 단일 접촉 지점을 나타냅니다. 터치 지점에는 터치 표면의 좌표계에서 위치를 나타내는 터치 x 좌표와 터치 y 좌표가 있습니다. 터치 표면이 게임패드의 위쪽, 아래쪽, 앞쪽 또는 뒤쪽에 있으면 터치 x 좌표는 좌우 축을 따라 측정되고, 그렇지 않으면 상하 축을 따라 측정됩니다. 터치 y 좌표는 수직 축을 따라 측정됩니다.
터치 표면이 게임패드의 왼쪽 또는 오른쪽 면에 있으면, 그 두 치수 중 어느 것도 수평 축과 정렬되지 않습니다.
터치 표면에는 표면 치수 입력 값이 있을 수 있습니다. 표면 너비와 표면 높이 입력 값은 터치 x 좌표 및 터치 y 좌표와 같은 단위로 표현된 터치 표면의 치수입니다. 터치 표면은 두 치수 값을 모두 갖거나 어느 값도 갖지 않습니다.
터치 지점은 새 접촉 지점일 수도 있고
이전 접촉의 연속일 수도 있습니다. 터치 지점은
사용자 에이전트가 그것이
이전 GamepadTouch가 나타낸
터치 지점의 연속이라고 식별하면
기존 활성
터치 지점의 일부입니다. 기존 활성
터치 지점의 일부인 터치 지점에 대한
활성
터치 지점 ID는 이전 GamepadTouch의
touchId입니다.
게임패드에는 햅틱 액추에이터가 있을 수 있습니다. 햅틱 액추에이터는 사용자가 느낄 수 있는 방식으로 게임패드를 움직일 수 있는 출력 컨트롤입니다. 햅틱 액추에이터는 사용자에게 피드백을 제공하는 햅틱 효과를 생성하는 데 사용될 수 있습니다. 여러 액추에이터의 진동은 결합되어 더 복잡한 효과를 생성합니다. 사용자 에이전트는 사용 가능한 게임패드에서 햅틱 액추에이터가 햅틱 효과를 재생하고 중지하도록 명령할 책임이 있습니다.
게임패드에는 전체 게임패드를 진동시키는 햅틱 효과를 재생할 수 있는 햅틱 액추에이터인 진동 액추에이터가 있을 수 있습니다.
햅틱 액추에이터에는 하나 이상의
GamepadHapticEffectType
값을 포함하는 지원되는
효과
유형의 목록이 있으며,
이는 게임패드가
사용 가능한 동안에는 변경될 수 없습니다.
이 인터페이스는 개별 게임패드 장치를 정의합니다.
WebIDL[Exposed=Window]
interface Gamepad {
readonly attribute DOMString id;
readonly attribute long index;
readonly attribute boolean connected;
readonly attribute DOMHighResTimeStamp timestamp;
readonly attribute GamepadMappingType mapping;
readonly attribute FrozenArray<double> axes;
readonly attribute FrozenArray<GamepadButton> buttons;
readonly attribute FrozenArray<GamepadTouch> touches;
[SameObject] readonly attribute GamepadHapticActuator vibrationActuator;
};
시스템과 통신하는 데 사용되는 알고리즘은 일반적으로 비동기적으로 완료되며, 게임패드 태스크 소스에 작업을 큐에 넣습니다.
Gamepad 인스턴스는
다음 표에 설명된 내부 슬롯으로 생성됩니다:
| 내부 슬롯 | 초기값 | 설명(비규범적) |
|---|---|---|
| [[connected]] |
false
|
장치가 시스템에 연결되어 있음을 나타내는 플래그 |
| [[timestamp]] | undefined |
이 Gamepad에 대한 데이터가 마지막으로 갱신된 시간
|
| [[axes]] | 빈 sequence |
이 장치가 노출하는 축의 현재 상태를 나타내는
double 값의
sequence
|
| [[buttons]] | 빈 sequence |
이 장치가 노출하는 버튼의 현재 상태를 나타내는
GamepadButton 객체의
sequence
|
| [[exposed]] |
false
|
Gamepad 객체가
스크립트에 노출되었음을 나타내는 플래그
|
| [[axisMapping]] | 빈 ordered map |
매핑되지 않은 축 인덱스에서
axes 배열의 인덱스로의 매핑
|
| [[axisMinimums]] | 빈 list | 각 축의 최소 논리 값을 포함하는 list |
| [[axisMaximums]] | 빈 list | 각 축의 최대 논리 값을 포함하는 list |
| [[buttonMapping]] | 빈 ordered map |
매핑되지 않은 버튼 인덱스에서
buttons 배열의 인덱스로의 매핑
|
| [[buttonMinimums]] | 빈 list | 각 버튼의 최소 논리 값을 포함하는 list. |
| [[buttonMaximums]] | 빈 list | 각 버튼의 최대 논리 값을 포함하는 list |
| [[touches]] | 빈 list | 사용자에 의해 생성된 터치의 목록이 있으면 이를 보관합니다. 게임패드가 터치 표면을 지원하지 않으면 목록은 비어 있는 상태로 남습니다. |
| [[nextTouchId]] | 0 |
다음 수신 터치에 사용할
touchId 값.
|
| [[vibrationActuator]] | undefined |
전체 게임패드를 진동시키는 햅틱 효과를 생성할 수 있는
GamepadHapticActuator 객체
|
id 속성
게임패드의 식별 문자열입니다. 이 문자열은 연결된 게임패드 장치의 브랜드나 스타일을 식별합니다.
id 문자열의 정확한 형식은 명시하지 않습니다.
사용자 에이전트는 장치를
고유하게 식별하지 않고 제품을 식별하는 문자열을 선택하는 것이
RECOMMENDED입니다. 예를 들어 USB 게임패드는
idVendor와 idProduct 값으로 식별될 수 있습니다.
일련번호나 Bluetooth 장치 주소와 같은 고유 식별자는
id 문자열에 포함되어서는
MUST NOT 됩니다.
index 속성
Navigator에서의
게임패드 인덱스입니다. 여러 게임패드가
사용자
에이전트에 연결되어 있을 때, 인덱스는 0부터 시작하여
선착순 기준으로 할당되어야 MUST 합니다.
게임패드의 연결이 끊어지면, 이전에 할당된 인덱스는 계속 연결되어 있는
게임패드에 재할당되어서는 MUST NOT 됩니다.
그러나 게임패드의 연결이 끊어진 뒤, 이후 같은 게임패드나 다른 게임패드가
연결되면, 이전에 사용된 가장 낮은 인덱스를 다시 사용해야
MUST 합니다.
connected
속성
이 객체가 나타내는 물리적 장치가 여전히 시스템에 연결되어 있는지를 나타냅니다.
게임패드가 물리적으로 분리되었거나, 전원이 꺼졌거나, 그 밖의 이유로
사용할 수 없게 되어 사용 불가 상태가 되면,
connected 속성은
false로 설정되어야 MUST 합니다.
connected getter 단계는 다음과 같습니다:
[[connected]]를 반환합니다.
timestamp
속성
timestamp는 작성자가 이
게임패드에 대한 axes 또는 buttons 속성이 마지막으로
갱신된 시간을 판단할 수 있게 합니다. 값은 시스템이 장치로부터
새 버튼 또는 축 입력
값을 받을 때마다
현재
고해상도
시간으로 설정되어야 MUST 합니다. 하드웨어에서 데이터가
수신되지 않은 경우,
timestamp는
Gamepad가 처음으로
스크립트에 사용 가능하게 된 시점의
현재
고해상도
시간이어야 MUST 합니다.
timestamp getter 단계는 다음과 같습니다:
[[timestamp]]를 반환합니다.
mapping
속성
이 장치에 사용 중인 매핑입니다. 사용자
에이전트가
장치의 배치를 알고 있다면,
mapping을
대응하는 GamepadMappingType
값으로 설정하여 매핑이 사용 중임을 나타내는 것이
SHOULD입니다.
게임패드 장치에 대한 매핑을 선택하려면 다음 단계를 실행합니다:
standard"를 반환합니다.
"를 반환합니다.
axes 속성
게임패드의 모든 축에 대한 값 배열입니다. 모든 축 값은 [-1 .. 1] 범위로 선형 정규화되어야 MUST 합니다. 컨트롤러가 지면에 수직이고 방향 스틱이 위를 가리키는 경우, -1은 "앞쪽" 또는 "왼쪽"에 대응하는 것이 SHOULD이며, 1은 "뒤쪽" 또는 "오른쪽"에 대응하는 것이 SHOULD입니다. 2D 입력 장치에서 온 축은 axes 배열에서 서로 이웃해 나타나는 것이 SHOULD이며, X 다음 Y 순서입니다. 축은 중요도가 감소하는 순서로 나타나는 것이 RECOMMENDED이며, 따라서 요소 0과 1은 일반적으로 방향 스틱의 X 및 Y 축을 나타냅니다. 사용자 에이전트가 다른 값 (또는 다른 순서의 값)을 반환해야 할 때까지 같은 객체가 반환되어야 MUST 합니다.
axes getter 단계는 다음과 같습니다:
buttons
속성
게임패드의 모든 버튼에 대한 버튼 상태 배열입니다. 버튼은 중요도가 감소하는 순서로 나타나는 것이 RECOMMENDED이며, 따라서 주 버튼, 보조 버튼, 제3 버튼 등이 buttons 배열의 요소 0, 1, 2, ...로 나타납니다. 사용자 에이전트가 다른 값(또는 다른 순서의 값)을 반환해야 할 때까지 같은 객체가 반환되어야 MUST 합니다.
buttons getter 단계는 다음과 같습니다:
[[buttons]]를 반환합니다.
touches
속성
모든 터치 표면에서 생성된
GamepadTouch 객체의
list입니다.
touches getter 단계는 다음과 같습니다:
[[touches]]를 반환합니다.
vibrationActuator 속성
장치의 기본 진동 액추에이터를 나타내는
GamepadHapticActuator 객체입니다.
vibrationActuator getter 단계는
다음과 같습니다:
[[vibrationActuator]]를 반환합니다.
시스템이 새 버튼 또는 축 입력 값을 받으면, 다음 단계를 실행합니다:
Gamepad
객체로 둡니다.
gamepad에 대해 게임패드 상태를 갱신하려면 다음 단계를 실행합니다:
[[timestamp]]를
now로 설정합니다.
Navigator
객체로 둡니다.
[[hasGamepadGesture]]가
false이고
gamepad가 게임패드 사용자 제스처를 포함하면:
[[hasGamepadGesture]]를
true로 설정합니다.
[[gamepads]]의 각
connectedGamepad에 대해
반복합니다:
null과 같지 않으면:
[[exposed]]를
true로 설정합니다.
[[timestamp]]를
now로 설정합니다.
Document로 둡니다; 그렇지 않으면
null로 둡니다.
null이 아니고
완전히
활성 상태이면, 게임패드 태스크 소스에
전역
태스크를
큐에 넣어,
GamepadEvent를 사용하고 그
gamepad
속성을 connectedGamepad로 초기화하여,
gamepad의 관련
전역 객체에서
gamepadconnected라는
이름의
이벤트를 발송합니다.
gamepad에 대해 축을 매핑하고 정규화하려면 다음 단계를 실행합니다:
unsigned long 값의
list로 둡니다.
[[axisMapping]][rawAxisIndex]로 둡니다.
[[axisMinimums]][rawAxisIndex]로 둡니다.
[[axisMaximums]][rawAxisIndex]로 둡니다.
[[axes]][axisIndex]를
normalizedValue로 설정합니다.
gamepad에 대해 버튼을 매핑하고 정규화하려면 다음 단계를 실행합니다:
unsigned long 값의
list로 둡니다.
[[buttonMapping]][rawButtonIndex]로 둡니다.
[[buttonMinimums]][rawButtonIndex]로 둡니다.
[[buttonMaximums]][rawButtonIndex]로 둡니다.
[[buttons]][mappedIndex]로 둡니다.
[[value]]를
normalizedValue로 설정합니다.
버튼에 순수한 눌림 또는 해제 상태를 나타내는 디지털 스위치가 있으면,
버튼이 눌린 경우 button.[[pressed]]를
true로, 눌리지 않은 경우 false로 설정합니다.
그렇지 않으면, 값이
버튼 누름 임계값을 넘는 경우
button.[[pressed]]를
true로, 임계값을 넘지 않는 경우 false로 설정합니다.
버튼이 터치를 감지할 수 있으면,
버튼이 현재 터치되고 있는 경우
button.[[touched]]를 true로 설정합니다.
그렇지 않으면, button.[[touched]]를
button.[[pressed]]로 설정합니다.
gamepad에 대해 터치를 기록하려면 다음 단계를 실행합니다:
Gamepad.[[touches]]는
비어 있습니다.
surfaceDimensions를
터치 표면의 장치 단위 최대 X 및 Y 치수로
width와
height가
초기화된 DOMRectReadOnly로
설정합니다.
GamepadTouch 객체로 둡니다.
surfaceId를
surfaceId로 설정합니다.
touchId를
활성 터치 지점의
touchId로 설정합니다.
touchId를
gamepad.[[nextTouchId]]로 설정하고
gamepad.[[nextTouchId]]를
증가시킵니다.
Gamepad에 여러 터치 표면이 있으면 터치 ID는 표면 전체에서 고유합니다.
position을
new
DOMPointReadOnly로
설정하되,
x는
장치 터치 표면에 상대적인 장치 X 좌표로 초기화하고,
-1이 가장 왼쪽 좌표이고 1이 가장 오른쪽 좌표가 되도록
[-1 .. 1]로 정규화하며,
y는
장치 터치 표면으로 초기화하고,
-1이 가장 위쪽 좌표이고 1이 가장 아래쪽 좌표가 되도록
[-1 .. 1]로 정규화합니다.
x = (2.0 * touchData.x / surfaceDimensions.width) -
1
y = (2.0 * touchData.y / surfaceDimensions.height) - 1
[[touches]]에
추가합니다.
연결된 게임패드 장치를 나타내는
새
Gamepad는 다음 단계를 수행하여 생성됩니다:
Gamepad
인스턴스로 둡니다:
id 속성을 게임패드의
식별 문자열로 초기화합니다.
index 속성을
gamepad에 대해
사용되지 않은
게임패드 인덱스 선택의 결과로 초기화합니다.
mapping 속성을
게임패드 장치에 대한
매핑 선택의
결과로 초기화합니다.
[[connected]]를 true로 설정합니다.
[[timestamp]]를
gamepad의 관련
전역 객체가 주어진
현재 고해상도
시간으로 설정합니다.
[[axes]]를
gamepad에 대한
축 초기화의 결과로 설정합니다.
[[buttons]]를
gamepad에 대한
버튼 초기화의 결과로 설정합니다.
[[vibrationActuator]]를
gamepad에 대한
GamepadHapticActuator
생성의 결과로 설정합니다.
gamepad에 대해 사용되지 않은 게임패드 인덱스를 선택하려면 다음 단계를 실행합니다:
Navigator
객체로 둡니다.
[[gamepads]]의
size − 1로 둡니다.
[[gamepads]][gamepadIndex]가
null이면, gamepadIndex를 반환합니다.
null을 navigator.[[gamepads]]에
추가합니다.
[[gamepads]]의
size − 1을 반환합니다.
gamepad에 대해 축을 초기화하려면 다음 단계를 실행합니다:
[[axisMinimums]]를
각 축 입력의 최소 논리 값을 포함하며
inputCount와 같은
size를 갖는
unsigned long 값의
list로 설정합니다.
[[axisMaximums]]를
각 축 입력의 최대 논리 값을 포함하며
inputCount와 같은
size를 갖는
unsigned long 값의
list로 설정합니다.
그렇지 않으면:
[[axisMapping]][rawInputIndex]를
canonicalIndex로 설정합니다.
그렇지 않으면, rawInputIndex를 unmappedInputList에 추가합니다.
[[axisMapping]][rawInputIndex]를
axisIndex로 설정합니다.
gamepad에 대해 버튼을 초기화하려면 다음 단계를 실행합니다:
[[buttonMinimums]]를
각 버튼 입력의 최소 논리 값을 포함하며
inputCount와 같은
size를 갖는
unsigned long 값의
list로 설정합니다.
[[buttonMaximums]]를
각 버튼 입력의 최대 논리 값을 포함하며
inputCount와 같은
size를 갖는
unsigned long 값의
list로 설정합니다.
그렇지 않으면:
[[buttonMapping]][rawInputIndex]
를 canonicalIndex로 설정합니다.
그렇지 않으면, rawInputIndex를 unmappedInputList에 추가합니다.
[[buttonMapping]][rawInputIndex]
를 buttonIndex로 설정합니다.
GamepadButton을
buttons에
추가합니다.
이 인터페이스는 그러한 입력을 지원하는 게임패드의 터치 표면에서의 터치를
정의합니다. 객체는 터치 지점을 고유하게 식별하는 터치
touchId로 구성되며, 이는
입력 매체(예: 손가락, 스타일러스 등)가 터치 장치에 접촉하는 시점부터
입력 매체가 더 이상 터치 장치에 접촉하지 않는 시점까지 유지됩니다.
WebIDLdictionary GamepadTouch {
unsigned long touchId;
octet surfaceId;
DOMPointReadOnly position;
DOMRectReadOnly? surfaceDimensions;
};
touchId 속성
surfaceId 속성
position 속성
x,
y 좌표를
보관하는 DOMPointReadOnly입니다.
z와 w 값은 현재 사용되지 않습니다. 각 좌표의 범위는 [-1 .. 1]로
정규화됩니다. x축에서 -1은 가장 왼쪽 좌표를 가리키고
1은 가장 오른쪽 좌표를 가리킵니다. y축에서 -1은 가장 위쪽 좌표를
가리키고 1은 가장 아래쪽 좌표를 가리킵니다.
surfaceDimensions 속성
width와
height로
정수 단위에서 초기화된
DOMRectReadOnly입니다.
사용할 수 없으면 null입니다.
이 열거형은 Gamepad에 대해 알려진 매핑 집합을 정의합니다.
WebIDLenum GamepadMappingType {
"",
"standard",
"xr-standard",
};
""
standard"
xr-standard"
Gamepad 객체 중
getGamepads()가 반환하는 것은
"xr-standard"의
mapping을
보고해서는 MUST NOT 됩니다.
GamepadHapticActuator는
햅틱 피드백을 목적으로 힘을 가할 수 있는 모터 또는
기타 액추에이터의 구성에 대응합니다.
WebIDL[Exposed=Window]
interface GamepadHapticActuator {
[SameObject] readonly attribute FrozenArray<GamepadHapticEffectType> effects;
Promise<GamepadHapticsResult> playEffect(
GamepadHapticEffectType type,
optional GamepadEffectParameters params = {}
);
Promise<GamepadHapticsResult> reset();
};
GamepadHapticActuator
인스턴스는 다음 표에 설명된 내부 슬롯으로 생성됩니다:
| 내부 슬롯 | 초기값 | 설명 |
|---|---|---|
| [[effects]] |
GamepadHapticEffectType의
빈 list.
|
액추에이터가 지원하는 효과를 나타냅니다. |
| [[playingEffectPromise]] |
null
|
어떤 효과를 재생하기 위한
Promise, 또는 재생 중인
효과가 없으면 null.
|
effects 속성
액추에이터가 지원하는 모든 햅틱 효과 유형을 나타내는
GamepadHapticEffectType 값의
배열입니다. 이 속성은
사용자 에이전트가 해당 유형의 효과 재생을
지원하지 않는 경우가 아니라면, 액추에이터가 지원하는
GamepadHapticEffectType 값을
나열합니다.
effects getter 단계는 다음과 같습니다:
[[effects]]를 반환합니다.
playEffect() 메서드
GamepadHapticEffectType
type 및
GamepadEffectParameters
params와 함께 호출되는
playEffect()
메서드 단계는 다음과 같습니다:
TypeError로
거부된
promise를 반환합니다.
Document로 둡니다.
null이거나,
document가
완전히
활성 상태가 아니거나, document의
가시성
상태가
"hidden"이면,
"InvalidStateError"
DOMException으로
거부된
promise를 반환합니다.
[[playingEffectPromise]]가
null이 아니면:
[[playingEffectPromise]]로
둡니다.
[[playingEffectPromise]]를
null로 설정합니다.
preempted"로
resolve합니다.
GamepadHapticActuator가
type의
유형으로 효과를 재생할 수 없으면,
이유
NotSupportedError로
거부된
promise를 반환합니다.
[[playingEffectPromise]]를
새 promise로 둡니다.
[[playingEffectPromise]]가
null이 아니면,
this의
관련
전역 객체와 함께
게임패드 태스크 소스에
전역
태스크를 큐에 넣어 다음 단계를 실행합니다:
[[playingEffectPromise]]가
null이면, 이 단계를 중단합니다.
[[playingEffectPromise]]를
"complete"로
resolve합니다.
[[playingEffectPromise]]를
null로 설정합니다.
[[playingEffectPromise]]를 반환합니다.
reset() 메서드
reset() 메서드
단계는 다음과 같습니다:
Document로 둡니다.
null이거나,
document가
완전히
활성 상태가 아니거나, document의
가시성
상태가
"hidden"이면,
"InvalidStateError"
DOMException으로
거부된
promise를 반환합니다.
[[playingEffectPromise]]가
null이 아니면, 다음 단계를
병렬로
수행합니다:
[[playingEffectPromise]]로
둡니다.
[[playingEffectPromise]]가
여전히 같으면,
this.[[playingEffectPromise]]를
null로 설정합니다.
preempted"로
resolve합니다.
complete"로
Resolve합니다
GamepadHapticActuator는
type이
[[effects]]
list에서 발견될 수 있으면,
type으로
효과를
재생할 수 있습니다.
GamepadHapticEffectType
type과
GamepadEffectParameters
params를 갖는 효과가
유효한 효과를 설명하는지
확인하려면,
다음 단계를 실행합니다:
GamepadHapticEffectType
type의 값이 주어지면, 다음에 따라 분기합니다:
dual-rumble"
false를 반환합니다.
trigger-rumble"
false를 반환합니다.
true를 반환합니다
액추에이터에서 햅틱 효과를
발행하려면, 사용자 에이전트는 장치에
type의 효과를 렌더링하도록 명령을 보내고,
제공된 params를 사용하게 하려고 해야
MUST 합니다. 사용자 에이전트는
params.startDelay가
0.0이 아닐 때 더 정확한 재생 타이밍을 위해 제공된
playEffectTimestamp를 사용하는 것이
SHOULD입니다. 사용자
에이전트는 호환성을 높이기 위해 효과를 수정할
MAY 있습니다. 예를 들어 럼블 모터용으로 의도된 효과는
럼블 모터는 없지만 파형 기반 햅틱을 지원하는 장치에 대해
파형 기반 효과로 변환될 수 있습니다.
액추에이터에서 햅틱 효과를 중지하려면, 사용자 에이전트는 현재 재생 중인 모든 효과를 중단하도록 장치에 명령을 보내야 MUST 합니다. 햅틱 효과가 중단된 경우, 액추에이터는 가능한 한 빨리 움직임이 없는 상태로 돌아가는 것이 SHOULD입니다.
document의
가시성 상태가
"hidden"이 되면, 각
GamepadHapticActuator
actuator에 대해 다음 단계를 실행합니다:
[[playingEffectPromise]]가
null이면, 이 단계를 중단합니다.
[[playingEffectPromise]]가
null이면, 이 단계를 중단합니다.
[[playingEffectPromise]]를
"preempted"로
Resolve합니다.
[[playingEffectPromise]]를
null로 설정합니다.
Gamepad의 기본 진동 액추에이터를 나타내는
새
gamepadHapticActuator는
다음 단계를 수행하여 생성됩니다:
GamepadHapticActuator 인스턴스로 둡니다.
supportedEffectsList를 빈
list로 둡니다.
GamepadHapticEffectType의 각 열거형 값
type에 대해,
사용자 에이전트가
해당 액추에이터에서 그 유형의 효과를 시작하도록 명령을 보낼 수 있으면,
type을
supportedEffectsList에 추가합니다.
[[effects]]를
supportedEffectsList로 설정합니다.
WebIDLenum GamepadHapticsResult {
"complete",
"preempted"
};
complete
햅틱 효과의 재생이 완료되었습니다.
preempted
현재 효과가 다른 효과에 의해 중지되었거나 대체되었습니다(즉, "선점됨").
효과 유형은 액추에이터가 효과 매개변수를 해석하는 방식을 정의합니다.
WebIDLenum GamepadHapticEffectType {
"dual-rumble",
"trigger-rumble"
};
dual-rumble" 효과 유형
"dual-rumble"은 표준
게임패드의 각 손잡이에 편심 회전 질량(ERM) 진동 모터가 있는 햅틱
구성을 설명합니다. 이 구성에서는 어느 모터든 전체 게임패드를
진동시킬 수 있습니다. 각 모터가 만드는 진동 효과는 서로 달라서
각각의 효과를 결합하여 더 복잡한 햅틱 효과를 만들 수 있습니다.
"dual-rumble" 효과는
이 유형의 액추에이터를 위한 고정 지속 시간, 일정 강도의 진동 효과입니다.
"dual-rumble"
효과는 startDelay,
duration,
strongMagnitude, 그리고
weakMagnitude로 정의되며,
모두 기본값이 0이므로 필수는 아닙니다.
strongMagnitude와
weakMagnitude는
저주파 및 고주파 진동에 대한 강도 수준을 설정하며, [0 .. 1] 범위로
정규화되고 기본값은 0입니다.
GamepadEffectParameters params가 주어졌을 때,
유효한
dual-rumble 효과는 유효한 duration, 유효한 startDelay를 가져야 하며,
strongMagnitude와
weakMagnitude는 모두
[0
.. 1] 범위 안에 있어야 합니다.
trigger-rumble" 효과 유형
"trigger-rumble"은
"dual-rumble"에 사용되는
두 손잡이 모터에 더해,
Standard Gamepad의 아래쪽 전면 버튼
(정규 인덱스 6 및 7을 가진 버튼) 각각에
진동 모터가 있는 햅틱 구성을 설명합니다. 이러한 버튼은 가장 흔히
스프링 장착 트리거 형태를 취합니다. 이 구성에서는 어느 모터든 버튼
표면에 국소적 햅틱 피드백을 제공할 수 있습니다.
"trigger-rumble"
효과는 이 유형의 액추에이터를 위한 고정 지속 시간, 일정 강도의
진동 효과입니다. "trigger-rumble"
효과는 startDelay,
duration,
strongMagnitude,
weakMagnitude,
leftTrigger, 그리고
rightTrigger로 정의되며,
모두 기본값이 0이므로 필수는 아닙니다.
startDelay,
duration,
strongMagnitude,
weakMagnitude는
"dual-rumble"과 같은
정의를 공유합니다.
leftTrigger와
rightTrigger는
각각 왼쪽 및 오른쪽 아래쪽 전면 버튼 진동의 강도 수준을 설정하며,
[0 .. 1] 범위로 정규화되고 기본값은 0입니다.
GamepadEffectParameters params가 주어졌을 때,
유효한 trigger-rumble 효과는 유효한 duration, 유효한 startDelay를 가져야 하며,
strongMagnitude,
weakMagnitude,
leftTrigger, 그리고
rightTrigger는
[0 ..
1] 범위 안에 있어야 합니다.
GamepadEffectParameters 사전은 햅틱 효과에서 사용하는 매개변수에
대한 키를 포함합니다. 각 키의 의미는 햅틱 효과에 의해 정의되며, 일부 키는
사용되지 않을 수 있습니다.
원치 않는 장시간 실행 효과를 완화하기 위해, 사용자 에이전트는 유효한 효과에 대해 전체 효과 지속 시간을 어떤 최대 지속 시간으로 제한할 MAY 수 있습니다. 사용자 에이전트가 최대 5초를 사용하는 것이 RECOMMENDED됩니다.
WebIDLdictionary GamepadEffectParameters {
unsigned long long duration = 0;
unsigned long long startDelay = 0;
double strongMagnitude = 0.0;
double weakMagnitude = 0.0;
double leftTrigger = 0.0;
double rightTrigger = 0.0;
};
duration
멤버
duration은
진동 효과의 지속 시간을 밀리초 단위로 설정합니다.
startDelay
멤버
startDelay는
playEffect()가
호출된 뒤 진동이 시작될 때까지의 지연 시간을 밀리초 단위로 설정합니다.
지연 구간 동안 액추에이터는 진동하지 않는 것이
SHOULD NOT입니다.
strongMagnitude 멤버
dual-rumble" 또는
"trigger-rumble" 효과에서
저주파 럼블에 대한 진동 크기입니다.
weakMagnitude 멤버
dual-rumble" 또는
"trigger-rumble" 효과에서
고주파 럼블에 대한 진동 크기입니다.
leftTrigger 멤버
trigger-rumble"
효과에서 아래쪽 왼쪽 전면 버튼(정규
인덱스 6) 럼블에 대한 진동 크기입니다.
rightTrigger 멤버
trigger-rumble" 효과에서
아래쪽 오른쪽 전면 버튼
(정규 인덱스 7) 럼블에 대한
진동 크기입니다.
WebIDL[Exposed=Window]
interface GamepadEvent: Event {
constructor(DOMString type, GamepadEventInit eventInitDict);
[SameObject] readonly attribute Gamepad gamepad;
};
gamepad 속성
gamepad 속성은 이 이벤트와 연결된
게임패드 데이터에 대한 접근을 제공합니다.
WebIDLdictionary GamepadEventInit : EventInit {
required Gamepad gamepad;
};
gamepad 멤버
Gamepad입니다.
각 장치 제조사는 많은 서로 다른 제품을 만들며, 각각 고유한 스타일과 버튼 및 축 배치를 가집니다. 사용자 에이전트는 가능한 한 이러한 장치를 많이 지원하도록 의도되어 있습니다.
또한 게임 콘솔에 의해 널리 쓰이게 된 사실상 표준 배치도 있습니다. 사용자 에이전트가 연결된 장치를 인식하면, 가능할 때 이를 정규 순서로 재매핑하는 것이 RECOMMENDED됩니다. 인식되지 않는 장치는 여전히 원시 형태로 노출되어야 합니다.
현재 하나의 정규 배치, 즉 Standard
Gamepad가 있습니다. 재매핑할 때 axes와
buttons의 인덱스는 아래 도표의
물리적 위치와 가능한 한 가깝게 대응해야 합니다. 또한
mapping은
"standard"로 설정되는 것이
SHOULD입니다.
Standard Gamepad 버튼은 네 개의 버튼으로 이루어진 왼쪽 클러스터, 네 개의 버튼으로 이루어진 오른쪽 클러스터, 세 개의 버튼으로 이루어진 중앙 클러스터, 그리고 게임패드의 왼쪽과 오른쪽 측면에 있는 한 쌍의 전면 버튼으로 배치됩니다. "Standard Gamepad"의 네 축은 왼쪽과 오른쪽에 하나씩 있는 한 쌍의 아날로그 스틱과 연결됩니다. 다음 표는 버튼/축과 그 물리적 위치를 설명합니다.
축 입력이 엄지스틱 축의 입력 값을 보고하고, 엄지스틱이 해당 Standard Gamepad 엄지스틱과 대략 같은 위치에 있으며, 축의 방향(상하 또는 좌우)이 Standard Gamepad 축의 방향과 일치하면, 그 축 입력은 Standard Gamepad 축을 나타냅니다. 같은 Standard Gamepad 축을 나타내는 축이 여러 개 있으면, 사용자 에이전트는 그중 하나를 Standard Gamepad 축으로 선택하고 다른 축에는 다른 인덱스를 할당하는 것이 SHOULD입니다.
버튼 입력이 버튼 또는 트리거의 입력 값을 보고하고, 그 버튼 또는 트리거가 해당 Standard Gamepad 버튼과 대략 같은 위치에 있으면, 그 버튼 입력은 Standard Gamepad 버튼을 나타냅니다.
축 또는 버튼 입력이 Standard Gamepad 축 또는 버튼을 나타내면, 그 정규 인덱스는 해당 Standard Gamepad 축 또는 버튼의 인덱스입니다.
| 유형 | 인덱스 | 위치 |
|---|---|---|
| 버튼 | 0 | 오른쪽 클러스터의 아래쪽 버튼 |
| 1 | 오른쪽 클러스터의 오른쪽 버튼 | |
| 2 | 오른쪽 클러스터의 왼쪽 버튼 | |
| 3 | 오른쪽 클러스터의 위쪽 버튼 | |
| 4 | 왼쪽 위 전면 버튼 | |
| 5 | 오른쪽 위 전면 버튼 | |
| 6 | 왼쪽 아래 전면 버튼 | |
| 7 | 오른쪽 아래 전면 버튼 | |
| 8 | 중앙 클러스터의 왼쪽 버튼 | |
| 9 | 중앙 클러스터의 오른쪽 버튼 | |
| 10 | 왼쪽 스틱 눌림 버튼 | |
| 11 | 오른쪽 스틱 눌림 버튼 | |
| 12 | 왼쪽 클러스터의 위쪽 버튼 | |
| 13 | 왼쪽 클러스터의 아래쪽 버튼 | |
| 14 | 왼쪽 클러스터의 왼쪽 버튼 | |
| 15 | 왼쪽 클러스터의 오른쪽 버튼 | |
| 16 | 중앙 클러스터의 중앙 버튼 | |
| 축 | 0 | 왼쪽 스틱의 수평 축(음수는 왼쪽/양수는 오른쪽) |
| 1 | 왼쪽 스틱의 수직 축(음수는 위/양수는 아래) | |
| 2 | 오른쪽 스틱의 수평 축(음수는 왼쪽/양수는 오른쪽) | |
| 3 | 오른쪽 스틱의 수직 축(음수는 위/양수는 아래) |
Gamepad 객체의 기능을 검사하는 것은
능동적 지문 채취 수단으로 사용될 수 있습니다. 사용자
에이전트는
지문 채취 표면을 줄이기 위해 API를 통해 노출되는 장치 정보를 변경할
MAY 있습니다. 예를 들어, 연결된 장치에 더 많거나 더 적은
입력이 있더라도 구현은 Gamepad 객체가
Standard Gamepad 배치에 정의된 정확한 수의 버튼과
축을 갖도록 요구할 수 있습니다.
[FINGERPRINTING-GUIDANCE]
이 절은 비규범적입니다.
아래 예제는 게임패드에 대한 일반적인 접근을 보여줍니다.
requestAnimationFrame()
메서드와의 관계에 유의하십시오.
function runAnimation() {
window.requestAnimationFrame(runAnimation);
for (const pad of navigator.getGamepads()) {
// todo; simple demo of displaying pad.axes and pad.buttons
console.log(pad);
}
}
window.requestAnimationFrame(runAnimation);
requestAnimationFrame()와의
조정
대화형 애플리케이션은 일반적으로
requestAnimationFrame()
메서드를 사용하여 애니메이션을 구동하며, 애니메이션을 사용자 게임패드
입력과 조정하고자 합니다. 따라서 게임패드 데이터는 애니메이션 콜백이
실행되기 직전에 가능한 한 가깝게, 그리고 애니메이션과 일치하는 빈도로
폴링되어야 합니다. 즉, 애니메이션 콜백이 60Hz로 실행되고 있다면,
게임패드 입력도 같은 비율로 샘플링되어야 합니다.
게임패드가 시스템에서 사용 가능하게 되면, 다음 단계를 실행합니다:
Document로 둡니다; 그렇지 않으면 null.
null이 아니고
"gamepad" 권한을
사용하도록
허용되지 않았으면, 이 단계를 중단합니다.
Gamepad로 둡니다.
Navigator
객체로 둡니다.
[[gamepads]][gamepad.index]를
gamepad로 설정합니다.
[[hasGamepadGesture]]가
true이면:
[[exposed]]를 true로 설정합니다.
null이 아니고
완전히
활성 상태이면, 이벤트를 발송합니다.
이벤트 이름은 gamepadconnected이고,
대상은 gamepad의 관련
전역 객체이며, GamepadEvent를
사용하고
그 gamepad 속성을
gamepad로 초기화합니다.
이 명세를 구현하는 사용자
에이전트는
gamepadconnected라는
이름의 새 DOM 이벤트를 제공해야 합니다. 해당 이벤트는
GamepadEvent 유형이어야
MUST 하며,
Window
객체에서 발송되어야 MUST 합니다.
사용자 에이전트는
사용자가 게임패드를 연결했음을 나타내기 위해 이 이벤트 유형을 발송해야
MUST 합니다. 페이지가 로드될 때 게임패드가 이미 연결되어
있었다면, 사용자가 버튼을 누르거나 축을 움직일 때
gamepadconnected 이벤트가
발송되는 것이 SHOULD입니다.
게임패드가 시스템에서 사용 불가 상태가 되면, 다음 단계를 실행합니다:
Gamepad로
둡니다.
[[connected]]를 false로 설정합니다.
Document로 둡니다; 그렇지 않으면 null.
[[exposed]]가 true이고
document가 null이 아니며
완전히
활성 상태이면, 이벤트를 발송합니다.
이벤트 이름은 gamepaddisconnected이고,
대상은 gamepad의 관련
전역 객체이며, GamepadEvent를 사용하고 그
gamepad 속성을
gamepad로 초기화합니다.
Navigator
객체로 둡니다.
[[gamepads]][gamepad.index]를
null로 설정합니다.
[[gamepads]]가
비어 있지 않고,
navigator.[[gamepads]]의 마지막
항목이
null인 동안,
navigator.[[gamepads]]의 마지막
항목을
제거합니다.
이 명세를 구현하는 사용자
에이전트는
gamepaddisconnected라는
이름의 새 DOM 이벤트를 제공해야 합니다. 해당 이벤트는
GamepadEvent 유형이어야
MUST 하며,
Window
객체에서 발송되어야 MUST 합니다.
게임패드가 사용자 에이전트에서 연결 해제될 때,
사용자 에이전트가 이전에 해당 게임패드에 대해
gamepadconnected 이벤트를
Window에
발송한 적이 있으면, gamepaddisconnected 이벤트는
같은 Window에
발송되어야 MUST 합니다.
축 및 버튼 변경 이벤트를 포함할지 제외할지, 그리고 이를 더
함께 묶을지("gamepadchanged"?), 어느 정도 분리할지("gamepadaxischanged"?),
또는 개별 축과 버튼별로 분리할지에 대해 더 많은 논의가 필요합니다.
이 명세는 이벤트 핸들러 등록을 용이하게 하기 위해
HTML의 WindowEventHandlers
인터페이스 믹스인을 확장하여
이벤트 핸들러
IDL 속성을 추가합니다.
WebIDLpartial interface mixin WindowEventHandlers {
attribute EventHandler ongamepadconnected;
attribute EventHandler ongamepaddisconnected;
};
이 명세는 문자열 "gamepad"로 식별되는 정책 제어 기능을 정의합니다. 그 기본 허용 목록은 *입니다.
문서의
권한
정책은 해당 문서의 어떤 콘텐츠가
getGamepads()에
접근하도록 허용되는지 결정합니다. 어떤 문서에서 비활성화되면, 문서의 어떤 콘텐츠도
getGamepads()을
사용하도록
허용되지 않으며,
gamepadconnected 및
gamepaddisconnected
이벤트도 발송되지 않습니다.
비규범적이라고 표시된 절뿐 아니라, 이 명세의 모든 작성 지침, 도표, 예제 및 참고는 비규범적입니다. 이 명세의 그 밖의 모든 것은 규범적입니다.
이 문서의 핵심 단어 MAY, MUST, MUST NOT, RECOMMENDED, SHOULD, 그리고 SHOULD NOT은 여기 표시된 것처럼 모두 대문자로 나타날 때, 그리고 그때에만 BCP 14 [RFC2119] [RFC8174]에 설명된 대로 해석됩니다.
이 절은 비규범적입니다.
다음 사람들이 이 문서의 개발에 기여했습니다.
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: