Команда @ ... GET - поля ввода со списком

Создает поле ввода со списком. Включена для совместимости с предыдущими версиями. Для приложений Visual FoxPro следует использовать элемент управления ComboBox.

Синтаксис

@ nRow, nColumn
GET MemVarName | FieldName 
FUNCTION cFormatCodes | PICTURE cFormatCodes
	[NAME ObjectName]
	[FONT cFontName [, nFontSize]]
	[STYLE cFontStyle]
	[DEFAULT Expression]
	[FROM ArrayName
		[RANGE nStartElement [, nElements]]]
	[SIZE nHeight, nWidth]
	[ENABLE | DISABLE]
	[MESSAGE cMessageText]
	[VALID lExpression1 | nExpression]
	[WHEN lExpression2]
	[COLOR SCHEME nSchemeNumber1 [, nSchemeNumber2] 
	| COLOR ColorPairList]

Параметры
@ nRow, nColumn
Задает местоположение поля ввода со списком. Аргументы nRow и nColumn представляют собой числовые выражения, которые определяют позицию левого верхнего угла поля.
Строки нумеруются сверху вниз. Первая строка имеет номер 0 в основном окне Visual FoxPro или в пользовательском окне.
В Visual FoxPro строка 0 это строка, расположенная непосредственно под системной строкой меню Visual FoxPro.
В FoxPro для Macintosh строка 0 это строка, расположенная непосредственно под строкой заголовка FoxPro.
В FoxPro для MS-DOS строка 0 это строка, которую занимает системная строка меню FoxPro. Подробнее о том, как, манипулируя системной строкой меню FoxPro для MS-DOS, разместить поле ввода со списком в строке 0, см. SET SYSMENU.
Столбцы нумеруются слева направо. Первый столбец имеет номер 0 в основном окне Visual FoxPro или в пользовательском окне.
Когда поле ввода со списком размещается в пользовательском окне, координаты его строки и столбца берутся относительно данного пользовательского окна, а не относительно основного окна Visual FoxPro.
В Visual FoxPro и FoxPro для Macintosh позиция поля ввода со списком в основном окне Visual FoxPro или в пользовательском окне определяется шрифтом этого окна. Большинство шрифтов допускают множество вариантов с различными размерами, а некоторые из них имеют пропорциональные промежутки. Номер строки зависит от высоты текущего шрифта, а номер столбца от средней ширины буквы в текущем шрифте.
В Visual FoxPro и FoxPro для Macintosh позицию поля ввода со списком можно задавать дробными значениями координат по строкам и столбцам.
В FoxPro для MS-DOS десятичные дробные значения, используемые в качестве координат по строкам и столбцам, округляются до ближайшего целого числа.
GET MemVarName | FieldName
Задает переменную памяти, элемент массива или поле, в котором сохраняется число, представляющее сделанный пользователем выбор. Если пользователь выходит из поля ввода со списком, нажимая клавишу Esc, значение параметра MemVarName или FieldName не изменяется.
Значение MemVarName или FieldName должно быть числового или символьного типа. Если значение MemVarName или FieldName символьного типа, сохраняется название выбранного элемента. Если значение MemVarName или FieldName числового типа, сохраняется номер, представляющий позицию элемента в списке.
Начальный выбор элемента
Когда поле ввода со списком активизируется, значение MemVarName или FieldName определяет, какой именно элемент списка должен быть вначале отображен внутри поля ввода (и следует ли вообще что-нибудь отображать).
Если значение MemVarName или FieldName числового типа, в поле ввода вначале будет отображен элемент, номер позиции которого задан этой переменной или полем. Например, если переменная памяти, элемент массива или поле содержит 1, то первоначально будет отображен первый элемент поля ввода со списком. Если значение MemVarName или FieldName не соответствует ни одному из элементов списка (то есть оно меньше единицы или больше общего числа элементов), поле ввода вначале будет пустым.
Если значение MemVarName или FieldName символьного типа, проводится сравнение этого значения с каждым элементом списка с учетом регистра символов. При сравнении все специальные символы, а также все начальные и конечные пробелы игнорируются. Если найден совпавший элемент, он и будет первоначально отображен внутри поля ввода. Если совпадений не обнаружится, то в поле ввода первоначально будет отображено символьное значение MemVarName или FieldName; кроме того, оно добавляется в конец списка в качестве временного элемента.
FUNCTION cFormatCodes | PICTURE cFormatCodes
Задает поле ввода со списком и его элементы. Нужно включить предложение FUNCTION, предложение PICTURE или оба эти предложения. Ни один из этих трех методов нельзя выделить в качестве предпочтительного. Предложение FUNCTION или PICTURE содержит код спецификации поля ввода со списком (^) и набор элементов списка.
Элементы можно также задать в предложении FROM Arrayname. В таком случае их не надо включать в предложение FUNCTION или PICTURE. Однако если вы задали предложение FROM Arrayname, все равно в предложение FUNCTION или PICTURE необходимо включить код ^.
Символьное выражение cFormatCodes предложения FUNCTION должно начинаться с символа ^. Чтобы создать элементы списка, после ^ через пробел перечислите элементы, разделяя их точками с запятой. В следующем примере создаются элементы с названиями Cash, Charge, Net 30 и Net 60:

... FUNCTION '^ Cash;Charge;Net 30;Net 60'... 

В символьном выражении cFormatCodes предложения PICTURE используется тот же синтаксис, что и в предложении FUNCTION, только в PICTURE выражение должно начинаться с символа @, за которым следует ^.
Например, следующее предложение PICTURE создает элементы Cash, Charge, Net 30 и Net 60:

... PICTURE '@^ Cash;Charge;Net 30;Net 60'... 

Можно задать и оба предложения FUNCTION и PICTURE. В этом случае символьное выражение cFormatCodes предложения FUNCTION должно содержать код ^, указывающий на создание поля ввода со списком, и может также включать после пробела список элементов, а в символьном выражении cFormatCodes предложения PICTURE можно указать названия других элементов.
В следующих примерах иллюстрируются разнообразные формы синтаксиса, которые можно использовать для создания поля ввода со списком. Во всех примерах поле ввода со списком помещается во второй строке и втором столбце. Список содержит четыре элемента с названиями Cash, Charge, Net 30 и Net 60. Он инициализируется содержимым переменной памяти gnChoice. Когда вы выбираете один из элементов этого списка, выбор сохраняется в переменной gnChoice.
Только предложение FUNCTION:

STORE 1 TO gnChoice
@ 2,2 GET gnChoice FUNCTION '^ Cash;Charge;Net 30;Net 60'
READ

STORE 1 TO gnChoice
STORE '^ Cash;Charge;Net 30;Net 60' TO gcMyFunc
@ 2,2 GET gnChoice FUNCTION gcMyFunc
READ

Только предложение PICTURE:
STORE 1 TO gnChoice
@ 2,2 GET gnChoice PICTURE '@^ Cash;Charge;Net 30;Net 60'
READ

STORE 1 TO gnChoice
@ 2,2 GET gnChoice PICTURE '@^' + ' Cash;Charge;Net 30;Net 60'
READ

Предложения FUNCTION и PICTURE:
STORE 1 TO gnChoice
@ 2,2 GET gnChoice FUNCTION '^' ;
	PICTURE ' Cash;Charge;Net 30;Net 60'
READ

STORE 1 TO gnChoice
@ 2,2 GET gnChoice FUNCTION '^ Cash;Charge' ;
	PICTURE ';Net 30;Net 60'
READ

Опции N, T, 2 и 3 предложений PICTURE и FUNCTION
В предложении FUNCTION или PICTURE после кода спецификации ^ можно задать дополнительные опции, модифицирующие поведение (опции N и T) и внешний вид (опции 2 и 3) поля ввода со списком.
Коды спецификации 2 и 3 допустимы только в FoxPro для Macintosh.

Опция	Описание
N	Не прекращает операцию READ при выборе элемента. Данное поведение принимается по умолчанию.
T	Прекращает команду READ при выборе элемента. 
2	Создает плоское (двумерное) поле ввода со списком. Такое поле ввода со списком используется по умолчанию в FoxPro для Macintosh.
3	Создает трехмерное поле ввода со списком.

Элементы поля ввода со списком с особыми возможностями
Определяя название элемента списка, можно назначить ему специальные характеристики. Например, используя специальные символы, можно назначить элементу клавишу доступа или сделать его недоступным.
Клавиши доступа
Для каждого элемента списка можно создать клавишу доступа, поставив в названии элемента перед нужным символом обратную косую черту со знаком "меньше" (\<). В следующем примере элементам Cash and Charge назначаются соответственно клавиши доступа C и R:

STORE 1 TO gnChoice
@ 2,2 GET gnChoice FUNCTION '^ \<Cash;Cha\<rge;Net 30;Net 60'
READ 

Подробнее о клавишах доступа см. главу 12 "Конструирование меню" Руководства разработчика.
Недоступные элементы
Элемент списка можно сделать недоступным, чтобы его нельзя было выбрать. Недоступные элементы изображаются в определенных для этого состояния цветах. Чтобы сделать какой-либо элемент списка недоступным, поставьте перед его названием обратную косую черту (\). Чтобы сделать недоступным все поле ввода со списком, задайте ключевое слово DISABLE.
В следующем примере делается недоступным элемент Charge:

STORE 1 TO gnChoice
@ 2,2 GET gnChoice FUNCTION '^ Cash;\Charge;Net 30;Net 60'
READ

NAME ObjectName
Допустимо только в Visual FoxPro.
Создает ссылку на поле ввода со списком как на объект, что позволяет манипулировать им, используя объектно-ориентированные свойства элемента управления ComboBox. Подробнее о манипулировании элементами управления FoxPro с помощью предложения NAME см. Элементы управления и объекты.
FONT cFontName [, nFontSize]
Допустимо только в Visual FoxPro и FoxPro для Macintosh.
Задает шрифт для поля ввода со списком и размер шрифта. Аргумент cFontName задает имя шрифта, а nFontSize размер шрифта в пунктах. Например, следующее предложение можно использовать для отображения элементов списка шрифтом Courier, имеющим размер 16 пунктов:
FONT 'Courier', 16
Если предложение FONT опущено, а поле ввода со списком помещается в основное окно Visual FoxPro, используется шрифт этого окна. Если предложение FONT опущено, а поле ввода со списком помещается в пользовательское окно, используется шрифт этого пользовательского окна.
Если вы задали предложение FONT, опустив размер шрифта nFontSize, используется 10-пунктовый шрифт.
В Visual FoxPro, если заданный шрифт отсутствует, его заменяет шрифт с похожими характеристиками.
В FoxPro для Macintosh, если заданный шрифт отсутствует, используется шрифт Chicago.
В FoxPro для MS-DOS предложение FONT игнорируется.
STYLE cFontStyle
Допустимо только в Visual FoxPro и FoxPro для Macintosh.
Задает стиль шрифта для элементов списка. Если опустить предложение STYLE, используется стиль Normal (нормальный).
В Visual FoxPro, если заданный стиль шрифта отсутствует, его заменяет стиль с похожими характеристиками.
В FoxPro для Macintosh, если заданный стиль шрифта отсутствует, используется стиль Normal.
В FoxPro для MS-DOS предложение STYLE игнорируется.
Стили шрифта, которые можно задавать в качестве cFontStyle, перечислены в следующей таблице.

Символ	Стиль шрифта
B	Bold (Полужирный)
C	Condense (Уплотненный; только в FoxPro для Macintosh)
E	Extend (Расширенный; только в FoxPro для Macintosh)
I	Italic (Курсив)
N	Normal (Нормальный)
O	Outline (Контурный)
Q	Opaque (Непрозрачный)
S	Shadow (Затененный)
-	Strikeout (Перечеркнутый; только в Visual FoxPro)
T	Transparent (Прозрачный)
U	Underline (Подчеркнутый)

Можно указать сразу несколько символов, задав комбинацию стилей. Например, следующее предложение задает полужирный курсив (Bold Italic):

STYLE 'BI'

DEFAULT Expression
Когда вы выбираете элемент из списка, этот выбор сохраняется в заданной переменной памяти, элементе массива или поле. Если задана несуществующая переменная, она будет автоматически создана и проинициализирована, при условии, что включено предложение DEFAULT. Однако если в этом предложении указать элемент массива, он не будет создан. Если заданная переменная памяти уже существует или если вы задали поле, предложение DEFAULT игнорируется.
Замечание Если предложение DEFAULT опущено и переменная памяти MemVarName не существует, Visual FoxPro сгенерирует сообщение об ошибке.
Выражение Expression предложения DEFAULT определяет тип создаваемой переменной памяти и ее первоначальное значение. Это должно быть числовое или логическое выражение. Ниже приведены примеры предложений DEFAULT для полей ввода со списком.

@ 2,2 GET gnChoice FUNCTION '^ Cash;Charge;Net 30;Net 60' ;
	DEFAULT 'Cash'
READ

@ 2,2 GET gnChoice FUNCTION '^ Cash;Charge;Net 30;Net 60';
	DEFAULT 3
READ

FROM ArrayName
Создает элементы списка на основе заранее определенного массива. Если вы создаете элементы с помощью предложения FROM ArrayName, нужно все равно указывать @^ в предложении PICTURE или ^ в предложении FUNCTION. Например:

... FROM gaMyArray PICTURE '@^'... 
... FROM gaMyArray FUNCTION '^'... 

Если задано предложение FROM ArrayName, все названия элементов, указанные в предложении PICTURE или FUNCTION, игнорируются. Список составляется из элементов массива ArrayName. Если массив одномерный, первый элемент списка создается из первого элемента массива, второй элемент списка ѕ из второго элемента массива и т.д.
Если массив двумерный, список создается только из элементов первого столбца массива. Первый элемент списка создается из первого элемента первого столбца, второй элемент списка ѕ из второго элемента первого столбца и т.д.

RANGE nStartElement [, nElements]

Позволяет указывать другой начальный элемент в массиве. Например, если массив одномерный и значение nStartElement равно 3, первый элемент списка создается из третьего элемента массива, второй элемент списка из четвертого элемента массива и т.д. По умолчанию элементы списка начинают создаваться с первого элемента массива.
Номер позиции элемента в двумерном массиве вычисляется по строкам. Допустим, вы создали следующий массив размерностью 3х3:

a b c
d e f
g h i

Если задан начальный элемент nStartElement, можно также указать число элементов массива, используемых для создания списка, с помощью числового выражения nElements. Если опустить значение nElements, в список включается содержимое всех элементов массива в заданном столбце, начиная с элемента nStartElement и кончая последним элементом столбца. Если массив двумерный, аргумент nElements обозначает количество элементов, которые берутся из столбца массива, содержащего начальный элемент nStartElement. Например, если значение nStartElement равно 2, а значение nElements 3, элементы списка создаются из второго элемента массива и двух следующих элементов того же столбца.
Содержимое поля ввода со списком можно менять динамически. Вы можете вставлять и удалять элементы списка, модифицируя массив. При выдаче команды SHOW GETS параметры предложения RANGE вычисляются заново. Если элемент nStartElement или число nElements изменились, список обновляется, отражая внесенные изменения.
Манипулировать массивами помогают функции ACOPY( ), ADEL( ), ADIR( ), AELEMENT( ), AFIELDS( ), AINS( ), ALEN( ), ASCAN( ), ASORT( ) и ASUBSCRIPT( ).
В следующем примере демонстрируется, как можно динамически изменять поле ввода со списком. Определяются две кнопки, Vegetable и Fruits, которые можно нажимать. Другая группа кнопок задает цвет овощей или фруктов (red, yellow или green). При нажатии очередной кнопки поле ввода со списком модифицируется и обновляется.

CLEAR
SET TALK OFF
STORE 1 TO gnColor, gnFruitOrVeg, gnListChoice, gnStart
DIMENSION gaFoodArray(4,3)
STORE 'Apples'		TO gaFoodArray(1,1)
STORE 'Bananas'		TO gaFoodArray(1,2)
STORE 'Limes'		TO gaFoodArray(1,3)
STORE 'Strawberries'	TO gaFoodArray(2,1)
STORE 'Lemons'		TO gaFoodArray(2,2)
STORE 'Grapes'		TO gaFoodArray(2,3)
STORE 'Radishes'		TO gaFoodArray(3,1)
STORE 'Corn'			TO gaFoodArray(3,2)
STORE 'Lettuce'		TO gaFoodArray(3,3)
STORE 'Beets'		TO gaFoodArray(4,1)
STORE 'Squash'		TO gaFoodArray(4,2)
STORE 'Celery'		TO gaFoodArray(4,3)
@ 9,2   SAY 'Color:'
@ 11,2  SAY 'Type:'
@ 9,10  GET gnColor  FUNCTION '*RH \<Red;\<Yellow;\<Green' ;
	SIZE 1, 9, 1 VALID PROC1( )
@ 11,10 GET gnFruitOrVeg FUNCTION '*RH \<Fruit;\<Vegetable' ;
	SIZE 1, 12, 1 VALID PROC2( )
@ 4,14  GET gnListChoice FUNCTION '^' FROM gaFoodArray ;
	RANGE gnStart,2
@ 14,17 GET gnOk FUNCTION '*T OK' DEFAULT 1 SIZE 1, 8
@ 10,0,10,41 BOX
@ 8,0,12,41  BOX
READ CYCLE
PROCEDURE PROC1
DO CASE
	CASE gnColor = 1
		IF gnFruitOrVeg = 1
			gnStart = 1
		ELSE
			gnStart = 7
		ENDIF
	CASE gnColor = 2
		IF gnFruitOrVeg = 1
			gnStart = 2
		ELSE
			gnStart = 8
		ENDIF
	CASE gnColor = 3
		IF gnFruitOrVeg = 1
			gnStart = 3
		ELSE
			gnStart = 9
		ENDIF
ENDCASE
STORE 1 TO gnListChoice
SHOW GETS
RETURN.T.

PROCEDURE PROC2
IF gnFruitOrVeg = 1
	DO CASE
		CASE gnColor = 1
			STORE 1 TO gnStart
		CASE gnColor = 2
			STORE 2 TO gnStart
		CASE gnColor = 3
			STORE 3 TO gnStart
	ENDCASE
ELSE
	DO CASE
		CASE gnColor = 1
			STORE 7 TO gnStart
		CASE gnColor = 2
			STORE 8 TO gnStart
		CASE gnColor = 3
			STORE 9 TO gnStart
	ENDCASE
ENDIF
STORE 1 TO gnListChoice
SHOW GETS
RETURN.T.

SIZE nHeight, nWidth
Задает ширину поля ввода со списком. Первый аргумент предложения SIZE nHeight игнорируется для полей ввода со списком, поскольку для них высота определяется количеством элементов списка. В качестве nHeight можно задать любое число. Ширина поля ввода со списком, выраженная в столбцах, задается аргументом nWidth. Если опустить предложение SIZE, ширина поля по умолчанию будет определяться длиной самого большого элемента списка.
В Visual FoxPro и FoxPro для Macintosh на размер поля ввода со списком влияет также его шрифт. Шрифт списка задается предложением FONT. Если это предложение опущено, в поле ввода со списком используется шрифт его родительского окна (основного окна Visual FoxPro или окна, определенного пользователем).
ENABLE
Делает поле ввода со списком доступным. По умолчанию поле ввода со списком становится доступным при выдаче команды READ. Предложение ENABLE можно включать в программу для напоминания о том, что полем ввода со списком можно пользоваться.
DISABLE
Запрещает активизацию поля ввода со списком при выдаче команды READ. Когда поле ввода со списком не активно, оно изображается определенными для данного состояния цветами, и пользователь не может его выбирать. О том, как сделать недоступными отдельные элементы списка, а не все поле ввода со списком, см. выше раздел "Недоступные элементы". Чтобы сделать недоступное поле ввода со списком доступным, используйте команду SHOW GET ENABLE.
MESSAGE cMessageText
Создает сообщение, которое выдается при выборе поля ввода со списком.
В Visual FoxPro и FoxPro для Macintosh сообщение выводится в строке состояния. Если строка состояния была отключена с помощью команды SET STATUS BAR OFF, сообщение располагается в последней строке основного окна Visual FoxPro.
В FoxPro для MS-DOS сообщение по умолчанию размещается в центре последней строки основного окна FoxPro; местоположение сообщения можно изменить командой SET MESSAGE.
VALID lExpression1 | nExpression
Санкционирует пользовательский ввод. Когда пользователь выбирает элемент из списка, вычисляется значение выражения VALID. Как правило, lExpression1 и nExpression представляют собой пользовательские функции. С помощью подобных функций можно выбирать другие элементы управления, делать их доступными или недоступными, открывать окно просмотра, открывать другие формы для ввода данных или переходить к новой записи. В качестве пользовательской функции можно задать команду CLEAR READ, которая прекращает операцию READ.
lExpression1
Когда в предложение VALID возвращается логическое значение, это значение игнорируется, а поле ввода со списком продолжает оставаться текущим элементом управления. Впрочем, можно задать пользовательскую функцию, которая возвращает в предложение VALID логическое значение и при этом активизирует другой элемент управления.
nExpression
Предложение VALID с числовым выражением используется для задания элемента управления, который следует активизировать после выбора элемента из списка. Подробнее об элементах управления см. Элементы управления и объекты.
Числовое выражение nExpression определяет одну из следующих трех ситуаций.
Если nExpression = 0, поле ввода со списком остается активным элементом управления.
Если значение nExpression положительно, оно указывает количество элементов управления, на которое следует продвинуться. Например, если поле ввода со списком является текущим элементом управления и VALID возвращает 1, активизируется следующий элемент управления. Если значение nExpression больше числа оставшихся элементов управления, команда READ прекращается (если только не выдана команда READ CYCLE, активизирующая элементы управления).
Если значение nExpression отрицательно, оно задает количество элементов управления, на которое нужно вернуться. Например, если поле ввода со списком является текущим элементом управления и VALID возвращает -1, активизируется предыдущий элемент управления. Если nExpression задает возврат далее первого элемента управления, команда READ прекращается (если только не выдана команда READ CYCLE, активизирующая элементы управления).
WHEN lExpression2
Задает условие, в соответствии с которым поле ввода со списком можно выбирать только в том случае, если значением выражения lExpression2 является "истина" (.T.). Если значением lExpression2 оказывается "ложь" (.F.), поле ввода со списком выбирать нельзя и если оно расположено между другими элементами управления, оно пропускается.
COLOR SCHEME nSchemeNumber1 [, nSchemeNumber2]
Задает цвета поля ввода со списком. Если не задано предложение COLOR, цвета поля будут определяться цветовой схемой основного окна Visual FoxPro; если поле ввода со списком предназначено для пользовательского окна, то его цвета определяются цветовой схемой этого окна.
По умолчанию цвета поля ввода со списком и его элементов берутся из цветовой схемы основного окна Visual FoxPro или активного пользовательского окна и цветовой схемы 2.
Первая цветовая схема nSchemeNumber1 определяет цвет самого поля ввода, когда оно выбрано, доступно или недоступно. Она также определяет цвет сообщения. Вторая цветовая схема nSchemeNumber2 определяет цвет элементов списка и обрамления поля ввода со списком.
COLOR ColorPairList
Задает цвета поля ввода со списком. В следующей таблице перечислены цветовые пары каждой цветовой схемы и контролируемые ими компоненты поля ввода со списком.

Номер цветовой пары	nSchemeNumber1 или окно вывода
5			Сообщение
6			Выбранное поле ввода со списком 
9			Доступные поля ввода со списком 
10			Недоступные поля ввода со списком 

Номер цветовой пары	nSchemeNumber2 или цветовая схема 2
1			Недоступные элементы
2			Доступные элементы
3			Обрамление
6			Выбранный элемент
7			Клавиши доступа

Список цветовых пар контролирует только цвета самого поля ввода, когда оно выбрано, доступно или недоступно, а также цвет сообщения (то есть цветовые атрибуты поля ввода со списком, контролируемые цветовой схемой nSchemeNumber1). Чтобы полностью контролировать цвета поля ввода со списком, нужно задать обе цветовые схемы.

В следующем примере показано, как заменить текущую цветовую схему другими, заранее определенными цветовыми схемами:

STORE 1 TO gnChoice
@ 2,2 GET gnChoice FUNCTION '^ Cash;Charge;Net 30;Net 60' ;
	COLOR SCHEME 4, 5
READ

Подробнее о цветовых схемах и цветовых парах см. Использование цветов.

Комментарии
В Visual FoxPro поле ввода со списком создается с помощью конструктора форм или DEFINE CLASS. Подробнее о совместимости элементов управления предыдущих версий FoxPro 2.x см. Элементы управления и объекты.
Подробнее о добавлении элементов управления в форму см. главу 9 "Создание форм" Руководства разработчика и Добавление объекта в контейнерный класс.
Когда вы выбираете поле ввода со списком, оно открывается и показывает список элементов, из которого можно выбрать нужный. Список элементов задается в предложении FUNCTION и/или PICTURE, содержащем код спецификации поля ввода со списком символ ^.


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем.