Перейти к публикации

NX Open создание таблицы в Drafting'е


AVetal

Рекомендованные сообщения

Есть ли в NX Open C++ функции для работы с таблицами в модуле Drafting?

Поиск в документации слов типа table, row, tabular ничего не дал.

Запись в журнал во время работы NX, вставка таблицы, изменение текста внутри нее, размеров и т.п., приводит только к описанию действий NX типа: Меню, Инструменты, Таблица, Вставить

journal.cxx

// ----------------------------------------------

// Menu: Insert->Tabular Note...

// ----------------------------------------------

// ----------------------------------------------

// Menu: Tools->Table->Edit

// ----------------------------------------------

// ----------------------------------------------

// Menu: ═рчрф

// ----------------------------------------------

// ----------------------------------------------

// Menu: Tools->Table->Merge Cells

// ----------------------------------------------

// ----------------------------------------------

// Menu: Tools->Journal->Stop

// ----------------------------------------------

Подозреваю, что Annotations можно сделать Таблицами.

Ссылка на сообщение
Поделиться на других сайтах


Есть ли в NX Open C++ функции для работы с таблицами в модуле Drafting?

Нету

Есть в С

ищи UF_TABNOT_...

Таблица не имеет того же типа что annotation

Ссылка на сообщение
Поделиться на других сайтах

UF_TABNOT нашел, а как саму таблицу инициализоровать?

Пример там нет где можно посмотреть. :wallbash: ,

Вот пример создания таблицы

double knuckled_profile_report::make_table(double offest)

{ int irc, n_rows, n_cols, num_sections, i, j, shift_row;  double pt[3];

  UF_TABNOT_section_prefs_t tabnote_section_prefs, tabnote_section_prefs_save;

  UF_TABNOT_cell_prefs_t	tabnote_cell_prefs,	tabnote_cell_prefs_save;

  tag_t work_view_tag, wcs_tag, m_tag, csys_tag;

  int mpi[100]; double mpr[70]; char rp[27+1], dp[27+1];

  UF_ATTR_value_t attr_val; char sval[UF_ATTR_MAX_STRING_LEN+1];

  double box[6], ymin, ymax;



  try

  {

  irc=UF_DRF_ask_preferences(mpi, mpr, rp, dp);

  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);



  irc=UF_CSYS_ask_wcs(&wcs_tag);

  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

  irc=UF_CSYS_create_matrix(matrix, &m_tag);

  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

  irc=UF_CSYS_create_temp_csys(map(0.0,-offest,pt), m_tag, &csys_tag);

  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);



  irc=UF_TABNOT_ask_default_section_prefs(&tabnote_section_prefs);

  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

  tabnote_section_prefs_save=tabnote_section_prefs;

	tabnote_section_prefs.attach_point = UF_TABNOT_attach_point_t(UF_TABNOT_attach_point_top_left);

	tabnote_section_prefs.max_height = 0L;



  irc=UF_TABNOT_ask_default_cell_prefs(&tabnote_cell_prefs);

  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

  tabnote_cell_prefs_save=tabnote_cell_prefs;

	tabnote_cell_prefs.is_vertical = false;

	tabnote_cell_prefs.nm_fit_methods = 2;

	tabnote_cell_prefs.fit_methods[0] = UF_TABNOT_fit_method_t(UF_TABNOT_fit_method_auto_size_row);

	tabnote_cell_prefs.fit_methods[1] = UF_TABNOT_fit_method_t(UF_TABNOT_fit_method_auto_size_col);

	tabnote_cell_prefs.format = UF_TABNOT_format_t(UF_TABNOT_format_text);

	tabnote_cell_prefs.horiz_just = UF_TABNOT_just_t(UF_TABNOT_just_left);

	tabnote_cell_prefs.vert_just  = UF_TABNOT_just_t(UF_TABNOT_just_middle);

	if(flag_table_line_color)

	tabnote_cell_prefs.bottom_line_cfw[0]=tabnote_cell_prefs.right_line_cfw[0]=table_line_color;

	if(flag_table_line_font)

	tabnote_cell_prefs.bottom_line_cfw[1]=tabnote_cell_prefs.right_line_cfw[1]=table_line_font;

	if(flag_table_line_width)

	tabnote_cell_prefs.bottom_line_cfw[2]=tabnote_cell_prefs.right_line_cfw[2]=table_line_width;

	tabnote_cell_prefs.text_height = mpr[44];

	if(flag_table_text_height) tabnote_cell_prefs.text_height=table_text_height;

	if(flag_table_text_color)  tabnote_cell_prefs.text_color=table_text_color;

	if(flag_table_text_width)  tabnote_cell_prefs.text_density=table_text_width;



  irc=UF_TABNOT_set_default_section_prefs(&tabnote_section_prefs);

  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

  irc=UF_TABNOT_set_default_cell_prefs(&tabnote_cell_prefs);

  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

  irc=UF_CSYS_set_wcs(csys_tag);

  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);



  irc=UF_TABNOT_create(&tabnote_section_prefs, pt, &tabnote_tag);

  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

  irc=UF_TABNOT_enable_automatic_update(false);

  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);



	irc=UF_TABNOT_ask_nm_rows(tabnote_tag, &n_rows);

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	for(i=0; i<n_rows; i++)

	{ tag_t row_tag;

	irc=UF_TABNOT_ask_nth_row(tabnote_tag, 0, &row_tag);

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	irc=UF_TABNOT_remove_row(row_tag);

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	}



	irc=UF_TABNOT_ask_nm_columns(tabnote_tag, &n_cols);

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	for(i=0; i<n_cols; i++)

	{ tag_t col_tag;

	irc=UF_TABNOT_ask_nth_column(tabnote_tag, 0, &col_tag);

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	irc=UF_TABNOT_remove_column(col_tag);

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	}



	n_rows=1+((int)segments.size()<table_number_of_rows?(int)segments.size():table_number_of_rows);

	i=segments.size()/(n_rows-1);

	n_cols=5*( (double)segments.size()/(n_rows-1)-i > 0 ? i+1 : i );



	for(i=0; i<n_rows; i++)

	{ tag_t row_tag;

	irc=UF_TABNOT_create_row(10.0, &row_tag);

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	irc=UF_TABNOT_add_row(tabnote_tag, row_tag, 0);

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	}



	for(i=0; i<n_cols; i++)

	{ tag_t col_tag;

	irc=UF_TABNOT_create_column(10.0, &col_tag);

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	irc=UF_TABNOT_add_column(tabnote_tag, col_tag, 0);

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	}



	std::vector < std::vector <tag_t> > vvcells;

	vvcells.reserve(n_rows);



	for(i=0; i<n_rows; i++)

	{ std::vector <tag_t> vbuff; tag_t row_tag;

	irc=UF_TABNOT_ask_nth_row(tabnote_tag, i, &row_tag);

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

		for (j=0; j<n_cols; j++)

		{ tag_t col_tag, cell_tag;

		irc=UF_TABNOT_ask_nth_column(tabnote_tag, j, &col_tag);

		if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

		irc=UF_TABNOT_ask_cell_at_row_col(row_tag, col_tag, &cell_tag);

		if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

		vbuff.push_back(cell_tag);

		}

	vvcells.push_back(vbuff);

	}





	for(i=0; i<(int)vvcells.at(0).size(); i++)

	{

	  if(1 == i%5)

	  {

	  irc=UF_TABNOT_set_cell_text(vvcells[0][i], "Distance Base");

	  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	  }

	  if(3 == i%5)

	  {

	  irc=UF_TABNOT_set_cell_text(vvcells[0][i], "Distance Top");

	  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	  }

	  if(4 == i%5)

	  {

	  irc=UF_TABNOT_set_cell_text(vvcells[0][i], "Knuckle Angle");

	  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	  }

	irc=UF_TABNOT_set_cell_prefs(vvcells[0][i], &tabnote_cell_prefs);

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	}



	int txt_prec=-1; bool txt_tr_zer=true;

	if(flag_table_text_precision)		 txt_prec   = table_text_precision;

	if(flag_table_text_keep_trail_zeroes) txt_tr_zer = table_text_keep_trail_zeroes;

	for(i=1, j=1, shift_row=-5; i<(int)table_segments.size(); i++, j++)

	{

	if((i-1)%(n_rows-1) == 0) { shift_row+=5; j=1; }

	irc=UF_TABNOT_set_cell_text(vvcells[j][shift_row+0], table_segments[i].get_index().c_str());

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	irc=UF_TABNOT_set_cell_text(vvcells[j][shift_row+1], table_segments[i].get_dist_base(txt_prec, txt_tr_zer).c_str());

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	irc=UF_TABNOT_set_cell_text(vvcells[j][shift_row+2], table_segments[i].get_index().c_str());

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	irc=UF_TABNOT_set_cell_text(vvcells[j][shift_row+3], table_segments[i].get_dist_top(txt_prec, txt_tr_zer).c_str());

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	irc=UF_TABNOT_set_cell_text(vvcells[j][shift_row+4], table_segments[i].get_angle().c_str());

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	}



	if(flag_table_line_color)

	{

	irc=UF_OBJ_set_color(tabnote_tag, table_line_color);

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	}

	if(flag_table_line_font)

	{

	irc=UF_OBJ_set_font(tabnote_tag, table_line_font);

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	}

	if(flag_table_line_width)

	{

	irc=UF_OBJ_set_line_width(tabnote_tag, table_line_width);

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	}

	if(flag_table_text_layer)

	{

	irc=UF_OBJ_set_layer(tabnote_tag, table_text_layer);

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	}



  irc=UF_TABNOT_enable_automatic_update(true);

  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

  irc=UF_DRAW_update_tabnot(tabnote_tag);

  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

  irc=UF_CSYS_set_wcs(wcs_tag);

  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);



  irc=UF_TABNOT_ask_nm_sections(tabnote_tag, &num_sections);

  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	attr_val.type=UF_ATTR_string; attr_val.value.string = sval;

	strcpy(sval, value_attribute_mk_type_tabnote);

	for(i=0; i<num_sections; i++)

	{ tag_t section_tag;

	irc=UF_TABNOT_ask_nth_section(tabnote_tag, i, &section_tag);

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	tabnote_sections.push_back(section_tag);

	irc=UF_ATTR_assign(section_tag, name_attribute_mk_type, attr_val);

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	}



  irc=UF_VIEW_ask_work_view(&work_view_tag);

  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

  irc=UF_VIEW_convert_to_model(work_view_tag, tabnote_tag);

  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);



  irc=UF_TABNOT_set_default_section_prefs(&tabnote_section_prefs_save);

  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

  irc=UF_TABNOT_set_default_cell_prefs(&tabnote_cell_prefs_save);

  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);



  irc=UF_MODL_ask_bounding_box (tabnote_sections[0], box);

  if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

  ymin=box[1]; ymax=box[4];

	for(i=1; i<num_sections; i++)

	{

	irc=UF_MODL_ask_bounding_box (tabnote_sections[i], box);

	if(irc) throw ug_err(THIS_FILE, __LINE__, irc);

	if(box[1] < ymin) ymin=box[1];

	if(box[4] > ymax) ymax=box[4];

	}



  }

  catch(base_err &e) { e.trace(THIS_FILE, __LINE__); throw; }

  catch(...)		 { base_err e(THIS_FILE, __LINE__, "System error"); throw e; }

return ymax-ymin;

}
Ссылка на сообщение
Поделиться на других сайтах

Таблице как объекту имя можно присвоить (помимо tag_t), чтоб найти его на листе (для проверки: есть ли такой объект или нет)?

Ссылка на сообщение
Поделиться на других сайтах

Таблице как объекту имя можно присвоить (помимо tag_t), чтоб найти его на листе (для проверки: есть ли такой объект или нет)?

Да таблице можно присвоить имя или назначить ей строковый аттрибут

Это позволит ее найти для модификации

Ссылка на сообщение
Поделиться на других сайтах

Имя получилось присвоить, проблема в перемещение таблицы в новую точку.

В UF TABNOT есть установка координат таблицы только при создании. Изменить координаты видимо можно, использовав UF DRF. Примение UF_DRF_set_origin(tabnot_tag, pt), где double pt[3] приводит к ошибке.

Только что....

проблему решил, применив вместо tabnot_tag section. Т.е. сначало ищем объект с необходимым именем и берем у него tag_t

UF_OBJ_cycle_by_name("MAIN_TABLE",&same_tab);

затем, если этот tag_t != NULL_TAG, определяем tag_t section

UF_TABNOT_ask_nth_section(same_tab, 0, &section);

и тут выставляем новые координаты:

pt[0]=x0;

pt[1]=y0;

pt[2]=0;

UF_DRF_set_origin (section, pt);

и табличка в необходимом месте, без её перестройки и без запоминания данных полей :)

Ссылка на сообщение
Поделиться на других сайтах
  • 3 года спустя...

А как редактировать найденную таблицу?

делаю вот так:

UF_OBJ_cycle_by_name("TABLE",&finded_table);

	if(finded_table!=NULL_TAG)

	{

		 uc1601("Табл был найден",1);

		 i =  UF_TABNOT_ask_nth_row(finded_table,1,&row);		

	}

	if(i == 0)

	{

		  uc1601("Получили row",1);		

	}

	else

	{

		uc1601("ошибка",1); 

	}
Получаю первым сообщение "табл был найден", а вторым "ошибка"

вчем проблема, :wallbash:

подскажите пожалуйста.

Ссылка на сообщение
Поделиться на других сайтах

int UF_OBJ_ask_type_and_subtype

(

tag_t object_id, 

int * type, 

int * subtype 

)



int UF_TABNOT_ask_nm_rows

(

tag_t tabnote, 

int * nm_rows 

)



int UF_get_fail_message

(

int fail_code, 

char message [ 133 ] 

)

Попробуй перевести код ошибки в текст

Посмотри сколько строк в таблице и есть ли там 2 строки

Посмотри действительно ли эта таблица

Ссылка на сообщение
Поделиться на других сайтах

nut888 Спасибо

Проблема была решена:

Изначально я задавал имя таблице вручную, т.е. тык п.км св-ва, ->общие имя. Думал что задаю имя таблице, а оказалось неизвестно чему.

задал имя через UF_OBJ_set_name и все стало работать.

:)

Ссылка на сообщение
Поделиться на других сайтах
  • 9 месяцев спустя...

Добрый вечер,подскажи пожалуйста в чем ошибка при создании таблицы на листе?Правильно ли я понимаю суть метода создания таблицы:есть шаблон таблицы 123_metric.prt и при помощи UF_TABNOT_create_from_template мы его подгружаем в на текущий лист или я ошибаюсь?Вот код программы:

#include <stdio.h>

#include <stdlib.h>

#include <uf.h>

#include <uf_ui.h>

#include <uf_curve.h>

#include <uf_drf.h>

#include <uf_disp.h>

#include <uf_obj.h>

#include <string.h>

#include <uf_object_types.h>

#include <uf_tabnot.h>

#include <uf_disp.h>

#include <uf_view.h>

#define UF_CALL(X) (report_error( __FILE__, __LINE__, #X, (X)))

static int report_error(char *file,int line, char *call,int irc)

{

if(irc)

{

char err[133],msg[133];

sprintf(msg, "*** ERROR code %d at line %d in %s:\n+++ ",irc,line,file);

UF_get_fail_message(irc,err);

/*NOTE:UF_PRINT_SYSLOG IS NEW IN V18*/

UF_print_syslog(msg,FALSE);

UF_print_syslog(err,FALSE);

UF_print_syslog("\n",FALSE);

UF_print_syslog(call,FALSE);

UF_print_syslog(";\n",FALSE);

if(!UF_UI_open_listing_window())

{

UF_UI_write_listing_window(msg);

UF_UI_write_listing_window(err);

UF_UI_write_listing_window("\n");

UF_UI_write_listing_window(call);

UF_UI_write_listing_window(";\n");

}

}

return(irc);

}

static void do_ugopen_api(void)

{

tag_t view_tag,tabular_note,cell,col,row;

int response;

double screen_pos[3]={0};

double origin[3]={0};

char template_name[133]="123_metric.prt"

int a[2]={0,0};

UF_UI_specify_screen_position(

"Input center",

NULL,

NULL,

screen_pos,

&view_tag,

&response );

origin[0]=screen_pos[0];

origin[1]=screen_pos[1];

UF_CALL(UF_TABNOT_create_from_template(template_name,origin,&tabular_note));

UF_CALL(UF_TABNOT_ask_nth_row(tabular_note,a[0],&row));

UF_CALL(UF_TABNOT_ask_nth_column(tabular_note,a[1],&col));

UF_CALL(UF_TABNOT_ask_cell_at_row_col(row,col,&cell));

UF_CALL(UF_TABNOT_set_cell_text(cell,"UXU"));

UF_CALL(UF_TABNOT_update(tabular_note));

}

void ufusr(char *param, int *retcode, int param_len)

{

if (!UF_CALL(UF_initialize()))

{

do_ugopen_api();

UF_CALL(UF_terminate());

}

}

int ufusr_ask_unload(void)

{

return (UF_UNLOAD_IMMEDIATELY);

}

Изменено пользователем anton.lucky.88
Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

Вы можете опубликовать сообщение сейчас, а зарегистрироваться позже. Если у вас есть аккаунт, войдите в него для написания от своего имени.
Примечание: вашему сообщению потребуется утверждение модератора, прежде чем оно станет доступным.

Гость
Ответить в тему...

×   Вставлено в виде отформатированного текста.   Вставить в виде обычного текста

  Разрешено не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставить изображения напрямую. Загрузите или вставьте изображения по ссылке.

  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу.




  • Сообщения

    • Артур8991
    • soldo
      @maxx2000 Спасибо за развернутый ответ, очень помогли! @ak762 Благодарю, хороший вариант.
    • ak762
      holder - держатель, и так как узел используется для закрепления инструмента, в адаптированном на русский я бы использовал резцедержатель  в конкретном случае похоже sleeve эквивалент collet т.е. цанга получается 5 spindle sleeve holder = 5-ти местный цанговый держатель/резцедержатель
    • ДОБРЯК
      А что еще остается делать. В Ансис точно частоты будут разные, даже не сомневайтесь...
    • ДОБРЯК
      Кроме собственных чисел нужно еще и собственные вектора найти. Вы даже не понимаете задачи. Надо решить квадратное уравнение, чтобы найти два собственных числа и вектора для задачи любой размерности. Такой глупости я еще не слышал. Поэтому и смеюсь над вашими знаниями, которые вы еще в детском саду получили. И этим гордитесь... :=)
    • maxx2000
      прямо по чертежу 1. инструмент 2.гайка цангового патрона типа ER 3. хвостовик цангового патрона 4 многоместный держатель 5. Фиксирующие винты   Открутите гайку цангового патрона и установите в неё цангу нужного размера, накрутите на место; Установите в цангу инструмент и затяните гайку цангового патрона; Ослабьте крепёжные винты на многоместном держателе и отрегулируйте положение инструмента; Затяните фиксирующие винты;
    • Ander
    • ak762
      я бы попросил у заказчика дать конкретную марку применяемого материала и использовать эти данные для расчета судя по данным с MatWeb https://www.matweb.com/search/DataSheet.aspx?MatGUID=08fb0f47ef7e454fbf7092517b2264b2 там разброс механических свойств материала существенный включая зависимость от наполнителя и способа изготовления    
    • Jesse
      потестил со смещённым колесом.. Если коротко, то печаль)) В модальнике прикладываю вращение в разные сторона, частота та же. Пробовал даже "гнуть в разные стороны" - извлекать деформированные модели, когда уск. своб. падения направлено вверх и вниз. В модальниках частота та же, без изменения.. @Борман@AlexKazну что ж, если выкрутиться никак, будем осваивать Ansys. Чё ещё остаётся делать?!)))) Вроде какие-то видосики есть на ютюбе. Спс за овтеты)
    • soldo
      Приветствую всех! Часто искала информацию на форуме, связанную с переводом, но кое-что не могу найти и хочу попросить о помощи. Я перевожу инструкцию для токарного автомата продольного точения и не очень хорошо понимаю все, что связано с креплением инструмента к станку. Конкретно меня интересуют следующие вопросы. Станок оснащен разными инструментальными блоками, есть суппорт с резцами, блок с инструментами для поперечного сверления и т.д.  И есть один блок, который на корявом английском называется 5 spindle sleeve holder, На этом блоке 5 шпинделей и на них можно закрепить инструмент для сверления, нарезания резьбы и растачивания. В названии этого блока фигурируют какие-то втулки (sleeve), предполагаю, что это патроны? Вот, что примерно написано в инструкции по поводу установки инструмента в этом блоке: (1) Ослабьте стопорный винт ② и установите режущий инструмент ① на втулку ③. (2) Затяните стопорный винт ② и закрепите режущий инструмент ① на втулке ③. (3) Ослабьте резьбу ⑤ и вставьте втулку ③ в блок ④ . (4) Переместите втулку ③ в направлении длины и отрегулируйте прямоугольное положение режущего инструмента ①. (5) После регулировки затяните резьбу ⑤ и зафиксируйте втулку ③. Мой вопрос: как можно назвать этот блок и что это за "втулка"?  Прикрепляю ссылку, на ней скриншоты из инструкции с общим видом инструментальной системы, 5-шпиндельного блока и соответствующих инструментов для сверления. https://imgur.com/a/fpBgmLA
×
×
  • Создать...