 
			
				27.07.2022, 17:22
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 Тлен 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 02.01.2010 
					
					
					
						Сообщений: 6,601
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		
		
	
		
		
		
		
		
			
				__________________ 
				29375, 35 
 
			 
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				27.07.2022, 19:19
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 Кандидат Javascript-наук 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 16.08.2018 
					
					
					
						Сообщений: 113
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		
	
 
	
		
			Сообщение от voraa
			 
		
	 | 
 
	| 
		Толку от них в интерпретируемом языке?
	 | 
 
	
 
 Этo понятно. 
Просто подчёркиваю, что поддерживаемые аппаратно инструкции на целевой машине никак не доступны с верхнего уровня, хотя возникает парадокс, когда программист вынужден реализовывать матричные/векторные функции своими силами и мириться с чудовищной просадкой производительности, так как сам язык не поддерживает матрицы, но процессор - поддерживает.  
То есть, процессор вынужден выполнять эрзац-операцию из тысяч других, хотя эту эрзац-функцию сам процессор - знает и может выполнить мгновенно! 
В этом и суть парадокса!   
Шейдеры для 3D же в браузерах как-то поддерживаются, передавая их чуть ли не напрямую в видеопроцессор. 
А вот предусмотреть подобие шейдеров для самого процессора - нигде не смогли.   
	
 
	
		
			Сообщение от voraa
			 
		
	 | 
 
	| 
		Js не зависит от процессора. Код должен выполняться везде, даже в кофеварке.
	 | 
 
	
 
 Да, я понимаю. JavaScript и так критикуют, что для простых вэб-страниц он слишком сложен, наворочен. 
Когда можно было обойтись более простым - тем же Visual Basic Script.
 
А вот  GLSL- основан на ANSI C! 
Это чуть ли ни всю мощь Си в браузер перенесли пользователю на службу - избыточно как-то.   
Понимаете? Парадокс!   Спасибо!   
Ресурс, конечно, устарел - написан до внедрения BigInt'ов, но он очень подробный и информативный. 
Хотя циклы там тоже имеются, что не хорошо для производительности.  
		
	
		
		
		
		
		
		
	
		
			
			
	
			
			
			
			
			
				 
			
			
			
			
			
			
				
			
			
			
		 
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				27.07.2022, 19:43
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 Кандидат Javascript-наук 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 16.08.2018 
					
					
					
						Сообщений: 113
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		Eсть вот такой вопрос. 
Вот часть кода: 
const	X64_getters	= {
		RAX	:function() { var n = this[0]; n.WIDTH = 64; return n; },
		EAX	:function() { var n = this[0]; n = (n & 0xFFFFFFFFn) | (this.SIGNED && (n & 0x80000000n) ? 0xFFFFFFFF00000000n : 0n); n.WIDTH = 32; return n; },
		AX	:function() { var n = this[0]; n = (n & 0xFFFFn) | (this.SIGNED && (n & 0x8000n) ? 0xFFFFFFFFFFFF0000n : 0n); n.WIDTH = 16; return n; },
		AL	:function() { var n = this[0]; n = (n & 0xFFn) | (this.SIGNED && (n & 0x80n) ? 0xFFFFFFFFFFFFFF00n : 0n); n.WIDTH = 8; return n; },
		AH	:function() { var n = this[0] >> 8n; n = (n & 0xFFn) | (this.SIGNED && (n & 0x80n) ? 0xFFFFFFFFFFFFFF00n : 0n); n.WIDTH = 8; return n; },
		SIGNED	:function() { this.SIGNED = true; return this; }
	};
for(var fn in X64_getters)
	BigUint64Array.prototype.__defineGetter__(fn, X64_getters[fn]);
Почему здесь попутный флаг SIGNED работает и передаётся внутрь функции, а вот ответное свойство WIDTH никак дальше не передаётся? 
Сейчас WIDTH мне необходимо как-то ввести для всё тех же операций с регистрами, так как необходимо знать ширину по имени регистра (сейчас это работает через имя регистра в строке с проверкой через switch-case, что не очень хорошо!)  
		
	
		
		
		
		
		
		
	
		
			
			
	
			
			
			
			
			
				 
			
			
			
			
			
			
				
			
			
			
		 
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				27.07.2022, 20:26
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 Профессор 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 03.02.2020 
					
					
					
						Сообщений: 2,777
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	| 
	
	
		
		
		
		
		 n.WIDTH = 64 
Что такое n? number? object? 
Судя по коду это число, BigInt. И нет никаких сообщений об ошибке? 
Это ведь не объект, а примитивный тип. У него не может быть свойств 
		
	
		
		
		
		
		
		
		
						  
				
				Последний раз редактировалось voraa, 27.07.2022 в 20:35.
				
				
			
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				27.07.2022, 20:49
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 Профессор 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 03.02.2020 
					
					
					
						Сообщений: 2,777
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		
	
 
	| 
		
			Сообщение от Alikberov
			
		
	 | 
 
	| 
		(сейчас это работает через имя регистра в строке с проверкой через switch-case, что не очень хорошо!
	 | 
 
	
 
 Создайте объект 
 
WITH = {
   RAX:64,
   EAX:32,
   AX:16,
....
}
И проверяйте по имени без switch/case  
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				27.07.2022, 22:39
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 Кандидат Javascript-наук 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 16.08.2018 
					
					
					
						Сообщений: 113
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		Думaю, без примера понять нельзя, так как я плохо понимаю (оказывается) объектную модель JavaScript. 
<html>
<head>
<script>
const	X64_getters	= {
		RAX	:function() { var n = this[0]; n = (n & 0xFFFFFFFFFFFFFFFFn) | (this.EXPAND_SIGN && (n & 0x8000000000000000n) ? 0xFFFFFFFFFFFFFFFF0000000000000000n : 0n); n.WIDTH = 16; return n; },
		EAX	:function() { var n = this[0]; n = (n & 0xFFFFFFFFn) | (this.EXPAND_SIGN && (n & 0x80000000n) ? 0xFFFFFFFF00000000n : 0n); n.WIDTH = 8; return n; },
		AX	:function() { var n = this[0]; n = (n & 0xFFFFn) | (this.EXPAND_SIGN && (n & 0x8000n) ? 0xFFFFFFFFFFFF0000n : 0n); n.WIDTH = 4; return n; },
		AL	:function() { var n = this[0]; n = (n & 0xFFn) | (this.EXPAND_SIGN && (n & 0x80n) ? 0xFFFFFFFFFFFFFF00n : 0n); n.WIDTH = 2; return n; },
		AH	:function() { var n = this[0] >> 8n; n = (n & 0xFFn) | (this.EXPAND_SIGN && (n & 0x80n) ? 0xFFFFFFFFFFFFFF00n : 0n); n.WIDTH = 2; return n; },
		RBX	:function() { var n = this[3]; n = (n & 0xFFFFFFFFFFFFFFFFn) | (this.EXPAND_SIGN && (n & 0x8000000000000000n) ? 0xFFFFFFFFFFFFFFFF0000000000000000n : 0n); n.WIDTH = 16; return n; },
		EBX	:function() { var n = this[3]; n = (n & 0xFFFFFFFFn) | (this.EXPAND_SIGN && (n & 0x80000000n) ? 0xFFFFFFFF00000000n : 0n); n.WIDTH = 8; return n; },
		BX	:function() { var n = this[3]; n = (n & 0xFFFFn) | (this.EXPAND_SIGN && (n & 0x8000n) ? 0xFFFFFFFFFFFF0000n : 0n); n.WIDTH = 4; return n; },
		BL	:function() { var n = this[3]; n = (n & 0xFFn) | (this.EXPAND_SIGN && (n & 0x80n) ? 0xFFFFFFFFFFFFFF00n : 0n); n.WIDTH = 2; return n; },
		BH	:function() { var n = this[3] >> 8n; n = (n & 0xFFn) | (this.EXPAND_SIGN && (n & 0x80n) ? 0xFFFFFFFFFFFFFF00n : 0n); n.WIDTH = 2; return n; },
		RCX	:function() { var n = this[1]; n = (n & 0xFFFFFFFFFFFFFFFFn) | (this.EXPAND_SIGN && (n & 0x8000000000000000n) ? 0xFFFFFFFFFFFFFFFF0000000000000000n : 0n); n.WIDTH = 16; return n; },
		ECX	:function() { var n = this[1]; n = (n & 0xFFFFFFFFn) | (this.EXPAND_SIGN && (n & 0x80000000n) ? 0xFFFFFFFF00000000n : 0n); n.WIDTH = 8; return n; },
		CX	:function() { var n = this[1]; n = (n & 0xFFFFn) | (this.EXPAND_SIGN && (n & 0x8000n) ? 0xFFFFFFFFFFFF0000n : 0n); n.WIDTH = 4; return n; },
		CL	:function() { var n = this[1]; n = (n & 0xFFn) | (this.EXPAND_SIGN && (n & 0x80n) ? 0xFFFFFFFFFFFFFF00n : 0n); n.WIDTH = 2; return n; },
		CH	:function() { var n = this[1] >> 8n; n = (n & 0xFFn) | (this.EXPAND_SIGN && (n & 0x80n) ? 0xFFFFFFFFFFFFFF00n : 0n); n.WIDTH = 2; return n; },
		RDX	:function() { var n = this[2]; n = (n & 0xFFFFFFFFFFFFFFFFn) | (this.EXPAND_SIGN && (n & 0x8000000000000000n) ? 0xFFFFFFFFFFFFFFFF0000000000000000n : 0n); n.WIDTH = 16; return n; },
		EDX	:function() { var n = this[2]; n = (n & 0xFFFFFFFFn) | (this.EXPAND_SIGN && (n & 0x80000000n) ? 0xFFFFFFFF00000000n : 0n); n.WIDTH = 8; return n; },
		DX	:function() { var n = this[2]; n = (n & 0xFFFFn) | (this.EXPAND_SIGN && (n & 0x8000n) ? 0xFFFFFFFFFFFF0000n : 0n); n.WIDTH = 4; return n; },
		DL	:function() { var n = this[2]; n = (n & 0xFFn) | (this.EXPAND_SIGN && (n & 0x80n) ? 0xFFFFFFFFFFFFFF00n : 0n); n.WIDTH = 2; return n; },
		DH	:function() { var n = this[2] >> 8n; n = (n & 0xFFn) | (this.EXPAND_SIGN && (n & 0x80n) ? 0xFFFFFFFFFFFFFF00n : 0n); n.WIDTH = 2; return n; },
		SIGNED	:function() { this.EXPAND_SIGN = true; return this; }
	};
for(var fn in X64_getters)
	BigUint64Array.prototype.__defineGetter__(fn, X64_getters[fn]);
var	X64 = new BigUint64Array(16);
X64[0] = 0xABCDEF0123456789n;
X64[1] = 0x7654321089ABCDEFn;
X64[2] = 0xF7E6D5C4B3A29180n;
X64[3] = 0xF0E1D2C3B4A59687n;
function main() {
	var	Widths = {
			RAX	:16,
			EAX	:8,
			AX	:4,
			AH	:2,
			AL	:2,
			RCX	:16,
			ECX	:8,
			CX	:4,
			CH	:2,
			CL	:2,
			RDX	:16,
			EDX	:8,
			DX	:4,
			DH	:2,
			DL	:2,
			RBX	:16,
			EBX	:8,
			BX	:4,
			BH	:2,
			BL	:2
		};
	var	hTable = document.getElementsByTagName("table")[0];
	var	hCells;
	var	row, cell, regId, reg, sreg, width, content, flag, x64;
	for(row = 0; row < hTable.rows.length; ++ row) {
		hCells = hTable.rows[row].cells;
		for(cell = 0; cell < hCells.length; ++ cell) {
			hCells[cell].style.width = "100%";
			hCells[cell].style.textAlign = "center";
			if("reg" in hCells[cell].dataset) {
				regId = hCells[cell].dataset.reg.toUpperCase();
				if(regId in X64) {
					reg = X64[regId];
					// Если тут не создать копию массива,
					sreg = (new BigUint64Array(X64)).SIGNED[regId];
					// опция SIGNED распространится не только на текущий момент чтения sreg - временно,
					// а на весь массив безвременно
					// sreg = X64.SIGNED[regId];	// Вот так - не работает: SIGNED установится насовсем!
					width = reg.WIDTH;
					flag = isFinite(width);
					if(!flag)
						width = regId in Widths ? Widths[regId] : 16;
					content = [];
					content.push("0".repeat(32) + reg.toString(16));
					content.push("0".repeat(32) + sreg.toString(16));
					hCells[cell].textContent = regId + ":" + (content[0].substr(-width * 2) + "/" + content[1].substr(-width * 2)).toUpperCase() + (flag ? "" : " !!!");
				} else
					hCells[cell].textContent = "???";
			}
		}
	}
}
</script>
</head>
<body onload='main()'>
<table style=white-space:pre>
<tr><td colspan=8 data-reg=RAX></td></tr>
<tr><td colspan=4>---</td><td colspan=4 data-reg=EAX></td></tr>
<tr><td colspan=6>---</td><td colspan=2 data-reg=AX></td></tr>
<tr><td colspan=6>---</td><td data-reg=AH></td><td data-reg=AL></td></tr>
<tr><td colspan=8 data-reg=RCX></td></tr>
<tr><td colspan=4>---</td><td colspan=4 data-reg=ECX></td></tr>
<tr><td colspan=6>---</td><td colspan=2 data-reg=CX></td></tr>
<tr><td colspan=6>---</td><td data-reg=CH></td><td data-reg=CL></td></tr>
<tr><td colspan=8 data-reg=RDX></td></tr>
<tr><td colspan=4>---</td><td colspan=4 data-reg=EDX></td></tr>
<tr><td colspan=6>---</td><td colspan=2 data-reg=DX></td></tr>
<tr><td colspan=6>---</td><td data-reg=DH></td><td data-reg=DL></td></tr>
<tr><td colspan=8 data-reg=RBX></td></tr>
<tr><td colspan=4>---</td><td colspan=4 data-reg=EBX></td></tr>
<tr><td colspan=6>---</td><td colspan=2 data-reg=BX></td></tr>
<tr><td colspan=6>---</td><td data-reg=BH></td><td data-reg=BL></td></tr>
</table>
</body>
Как видно, всюду - восклицательные знаки. Признак того, что ширину слова приходится читать из таблицы - getter её не передаёт. 
А ещё прроблема - необходимость копировать массив из-за безвременного действия опции SIGNED.
 
Что я не понимаю и делаю не так?   
		
	
		
		
		
		
		
		
		
						  
				
				Последний раз редактировалось Alikberov, 27.07.2022 в 22:46.
				
				
			
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				28.07.2022, 09:00
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 Профессор 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 03.02.2020 
					
					
					
						Сообщений: 2,777
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		
	
 
	| 
		
			Сообщение от Alikberov
			
		
	 | 
 
	| 
		Как видно, всюду - восклицательные знаки.
	 | 
 
	
 
 Не понял о чем это.
 
	
 
	| 
		
			Сообщение от Alikberov
			
		
	 | 
 
	| 
		так как я плохо понимаю (оказывается) объектную модель JavaScript.
	 | 
 
	
 
 В js есть примитивные типы: number, string, boolean, undefined, null, symbol,  bigint
Все остальное - объекты. 
Свойства и методы могут быть только у объектов. 
Нельзя задать свойство примитивному типу 
Ну нельзя так 
let b = true; 
b.prop = 42; 
if (b.prop) {}
 
Вы пишите n.WITH = 16. Но n - bigint. Примитивный тип. 
	
 
	| 
		
			Сообщение от Alikberov
			
		
	 | 
 
	| 
		А ещё прроблема - необходимость копировать массив из-за безвременного действия опции SIGNED.
	 | 
 
	
 
 Только сделать опцию SIGNED временной. Обнулять после первого использования 
Т.е. например так
 
RAX :function() { 
  var n = this[0]; n = (n & 0xFFFFFFFFFFFFFFFFn) | 
(this.EXPAND_SIGN && (n & 0x8000000000000000n) ? 
0xFFFFFFFFFFFFFFFF0000000000000000n : 0n);
 /*n.WIDTH = 16; */
  this.EXPAND_SIGN = false; //!!!
  return n; 
},
 
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				28.07.2022, 13:35
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 Кандидат Javascript-наук 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 16.08.2018 
					
					
					
						Сообщений: 113
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		
	
 
	
		
			Сообщение от voraa
			 
		
	 | 
 
	| 
		Не понял о чем это.
	 | 
 
	
 
 
width = reg.WIDTH;
flag = isFinite(width);
if(!flag)
	width = regId in Widths ? Widths[regId] : 16;
 Как видно, всюду - восклицательные знаки.  Признак того, что ширину слова приходится читать из таблицы - getter её не передаёт.  
	
 
	
		
			Сообщение от voraa
			 
		
	 | 
 
	
		В js есть примитивные типы: number, string, boolean, undefined, null, symbol, bigint 
Все остальное - объекты. 
Свойства и методы могут быть только у объектов. 
Нельзя задать свойство примитивному типу
	 | 
 
	
 
 Почему тогда  это работает? 
Я  тренировался специально над Number, чтобы затем завернуть всё в алгоритм выше. Но не работает!   
В чём подвох? 
	
 
	
		
			Сообщение от voraa
			 
		
	 | 
 
	
		Вы пишите n.WITH = 16. Но n - bigint. Примитивный тип. 
Только сделать опцию SIGNED временной. Обнулять после первого использования 
Т.е. например так
	 | 
 
	
 
 Я тоже думал о таком костыле, но надеялся, что в JS есть возможность стрюковать.  
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				28.07.2022, 14:09
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 Профессор 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 03.02.2020 
					
					
					
						Сообщений: 2,777
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		
	
 
	| 
		
			Сообщение от Alikberov
			
		
	 | 
 
	| 
		Почему тогда это работает?
	 | 
 
	
 
 И как это работает? 
Приведите рабочий пример, что бы я мог написать
 
let n = 10
console.log (n.ME);
 
или 
 
console.log (n.PERSON)
 
У каких то примитивны типов есть объекты - обертки. При необходимости, примитивный тип превращается в объект со свойствами. Так
 
'abc'.length
 
на самом деле выполняется, как
 
(new String('abc')).length
Т.е строка, сначала, временно превращается в объект со свойствами и методами. но потом этот объект исчезает, если конечно не присвоить его чему то
 
let s = new String ('abc')
s.BYTEWIDTH = 6;
console.log (s.length, s.BYTEWIDTH) // 3 6
console.log (typeof s) // "object" !!!Но
console.log (s + 'd') // 'abcd' !!!И даже
Но вроде, как у BigInt нет такой оболочки  
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				28.07.2022, 15:11
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 Кандидат Javascript-наук 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 16.08.2018 
					
					
					
						Сообщений: 113
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		
	
 
	
		
			Сообщение от voraa
			 
		
	 | 
 
	
		И как это работает? 
Приведите рабочий пример, что бы я мог написать
	 | 
 
	
 
 
Number.prototype.__defineGetter__
	("ME", function() {
		this.PERSON = "Me";
		return this;
	});
Number.prototype.__defineGetter__
	("HERE", function() {
		this.PLACE = "Here";
		return this;
	});
var	Man = new Number(1536);
var	Logs = [];
try {
	Logs.push(`Man: ${Man}`);
	} catch(e) {}
try {
	Logs.push(`Man.ME: ${Man.ME}`);
	} catch(e) {}
try {
	Logs.push(`Man.HERE: ${Man.HERE}`);
	} catch(e) {}
try {
	Logs.push(`Man.ME.HERE: ${Man.ME.HERE}`);
	} catch(e) {}
try {
	Logs.push(`Man.HERE.ME: ${Man.HERE.ME}`);
	} catch(e) {}
try {
	Logs.push(`Man.ME.PERSON: ${Man.ME.PERSON}`);
	} catch(e) {}
try {
	Logs.push(`Man.HERE.PLACE: ${Man.HERE.PLACE}`);
	} catch(e) {}
try {
	Logs.push(`Man.ME.HERE.PLACE: ${Man.ME.HERE.PLACE}`);
	} catch(e) {}
try {
	Logs.push(`Man.HERE.ME.PLACE: ${Man.HERE.ME.PLACE}`);
	} catch(e) {}
try {
	Logs.push(`Man.ME.HERE.PERSON: ${Man.ME.HERE.PERSON}`);
	} catch(e) {}
try {
	Logs.push(`Man.HERE.ME.PERSON: ${Man.HERE.ME.PERSON}`);
	} catch(e) {}
console.log(Logs.join("\n"));
alert(Logs.join("\n"));
 
		
	
		
		
		
		
		
		
	
		
			
			
	
			
			
			
			
			
				 
			
			
			
			
			
			
				
			
			
			
		 
		
	
	
	 | 
 
 
	 
		 | 
 
 
 
 
 
 
	 | 
 
 
 |