static int write_chan(struct tty_struct * tty, struct file * file,
		      unsigned char * buf, unsigned int nr)
{
	struct wait_queue wait = { current, NULL };
	int c;
	unsigned char *b = buf;
	int retval = 0;

	/* Job control check -- must be done at start (POSIX.1 7.1.1.4). */
	if (L_TOSTOP(tty) && file->f_inode->i_rdev != CONSOLE_DEV) {
		retval = check_change(tty, tty->line);
		if (retval)
			return retval;
	}

	add_wait_queue(&tty->write_q.proc_list, &wait);
	while (1) {
		current->state = TASK_INTERRUPTIBLE;
		if (current->signal & ~current->blocked) {
			retval = -ERESTARTSYS;
			break;
		}
		if (tty_hung_up_p(file) || (tty->link && !tty->link->count)) {
			retval = -EIO;
			break;
		}
		while (nr > 0) {
			c = get_fs_byte(b);
			/* Care is needed here: opost() can abort even
			   if the write_q is not full. */
			if (opost(c, tty) < 0)
				break;
			b++; nr--;
		}
		TTY_WRITE_FLUSH(tty);
		if (!nr)
			break;
		if (EMPTY(&tty->write_q) && !need_resched)
			continue;
		if (file->f_flags & O_NONBLOCK) {
			retval = -EAGAIN;
			break;
		}
		schedule();
	}
	current->state = TASK_RUNNING;
	remove_wait_queue(&tty->write_q.proc_list, &wait);
	return (b - buf) ? b - buf : retval;
}
Exemple #2
0
/* Simulate how the CPU works. */
void cpu_exec(volatile uint32_t n) {
	if(nemu_state == END) {
		printf("Program execution has ended. To restart the program, exit NEMU and run again.\n");
		return;
	}
	nemu_state = RUNNING;

#ifdef DEBUG
	volatile uint32_t n_temp = n;
#endif

	setjmp(jbuf);

	for(; n > 0; n --) {
#ifdef DEBUG
		swaddr_t eip_temp = cpu.eip;
		if((n & 0xffff) == 0) {
			/* Output some dots while executing the program. */
			fputc('.', stderr);
		}
#endif

		/* Execute one instruction, including instruction fetch,
		 * instruction decode, and the actual execution. */
		int instr_len = exec(cpu.eip);

		cpu.eip += instr_len;

#ifdef DEBUG
		print_bin_instr(eip_temp, instr_len);
		strcat(asm_buf, assembly);
		Log_write("%s\n", asm_buf);
		if(n_temp < MAX_INSTR_TO_PRINT) {
			printf("%s\n", asm_buf);
		}
#endif

        if (check_change()) {
            show_watchpoint();
            break;
        }

		if(nemu_state != RUNNING) { return; }
	}

	if(nemu_state == RUNNING) { nemu_state = STOP; }
}
/*
 * This only works as the 386 is low-byte-first
 */
static int set_termio(struct tty_struct * tty, struct termio * termio,
			int channel)
{
	int i;
	struct termio tmp_termio;
	struct termios old_termios = *tty->termios;

	i = check_change(tty, channel);
	if (i)
		return i;
	for (i=0 ; i< (sizeof (*termio)) ; i++)
		((char *)&tmp_termio)[i]=get_fs_byte(i+(char *)termio);

	/* take care of the packet stuff. */
	if ((tmp_termio.c_iflag & IXON) &&
	    ~(tty->termios->c_iflag & IXON))
	  {
	     tty->status_changed = 1;
	     tty->ctrl_status |= TIOCPKT_DOSTOP;
	  }

	if (~(tmp_termio.c_iflag & IXON) &&
	    (tty->termios->c_iflag & IXON))
	  {
	     tty->status_changed = 1;
	     tty->ctrl_status |= TIOCPKT_NOSTOP;
	  }

	*(unsigned short *)&tty->termios->c_iflag = tmp_termio.c_iflag;
	*(unsigned short *)&tty->termios->c_oflag = tmp_termio.c_oflag;
	*(unsigned short *)&tty->termios->c_cflag = tmp_termio.c_cflag;
	*(unsigned short *)&tty->termios->c_lflag = tmp_termio.c_lflag;
	tty->termios->c_line = tmp_termio.c_line;
	for(i=0 ; i < NCC ; i++)
		tty->termios->c_cc[i] = tmp_termio.c_cc[i];

	if (tty->set_termios)
		(*tty->set_termios)(tty, &old_termios);

	return 0;
}
static int set_termios(struct tty_struct * tty, struct termios * termios,
			int channel)
{
	int i;
	struct termios old_termios = *tty->termios;

	i = check_change(tty, channel);
	if (i)
		return i;
	for (i=0 ; i< (sizeof (*termios)) ; i++)
		((char *)tty->termios)[i]=get_fs_byte(i+(char *)termios);

	/* puting mpty's into echo mode is very bad, and I think under
	   some situations can cause the kernel to do nothing but
	   copy characters back and forth. -RAB */
	if (IS_A_PTY_MASTER(channel)) tty->termios->c_lflag &= ~ECHO;

	if (tty->set_termios)
		(*tty->set_termios)(tty, &old_termios);

	return 0;
}
Exemple #5
0
int get_line P1H(void)
#line 428 "./cwebdir/common.w"
{
restart:
if(changing&&include_depth==change_depth)
/*27:*/
#line 537 "./cwebdir/common.w"
{
change_line++;
if(!input_ln(change_file)){
err_print("! Change file ended without @z");

buffer[0]= '@';buffer[1]= 'z';limit= buffer+2;
}
if(limit> buffer){
if(change_pending){
if_section_start_make_pending(0);
if(change_pending){
changed_section[section_count]= 1;change_pending= 0;
}
}
*limit= ' ';
if(buffer[0]=='@'){
if(xisupper(buffer[1]))buffer[1]= tolower(buffer[1]);
if(buffer[1]=='x'||buffer[1]=='y'){
loc= buffer+2;
err_print("! Where is the matching @z?");

}
else if(buffer[1]=='z'){
prime_the_change_buffer();changing= !changing;print_where= 1;
}
}
}
}

/*:27*/
#line 431 "./cwebdir/common.w"
;
if(!changing||include_depth> change_depth){
/*26:*/
#line 520 "./cwebdir/common.w"
{
cur_line++;
while(!input_ln(cur_file)){
print_where= 1;
if(include_depth==0){input_has_ended= 1;break;}
else{
fclose(cur_file);include_depth--;
if(changing&&include_depth==change_depth)break;
cur_line++;
}
}
if(!changing&&!input_has_ended)
if(limit-buffer==change_limit-change_buffer)
if(buffer[0]==change_buffer[0])
if(change_limit> change_buffer)check_change();
}

/*:26*/
#line 433 "./cwebdir/common.w"
;
if(changing&&include_depth==change_depth)goto restart;
}
if(input_has_ended)return 0;
loc= buffer;*limit= ' ';
if(buffer[0]=='@'&&(buffer[1]=='i'||buffer[1]=='I')){
loc= buffer+2;*limit= '"';
while(*loc==' '||*loc=='\t')loc++;
if(loc>=limit){
err_print("! Include file name not given");

goto restart;
}
if(include_depth>=max_include_depth-1){
err_print("! Too many nested includes");

goto restart;
}
include_depth++;
/*25:*/
#line 474 "./cwebdir/common.w"
{
#line 200 "./cwebdir/comm-w2c.ch"
char*cur_file_name_end= cur_file_name+max_file_name_length-1;
char*k= cur_file_name;
#line 479 "./cwebdir/common.w"

if(*loc=='"'){
loc++;
while(*loc!='"'&&k<=cur_file_name_end)*k++= *loc++;
if(loc==limit)k= cur_file_name_end+1;
}else
while(*loc!=' '&&*loc!='\t'&&*loc!='"'&&k<=cur_file_name_end)*k++= *loc++;
if(k> cur_file_name_end)too_long();

*k= '\0';
#line 207 "./cwebdir/comm-w2c.ch"
if((found_filename= kpse_find_cweb(cur_file_name))!=NULL&&
(cur_file= fopen(found_filename,"r"))!=NULL){

if(strlen(found_filename)<max_file_name_length){
strcpy(cur_file_name,found_filename);
free(found_filename);
}
#line 490 "./cwebdir/common.w"
cur_line= 0;print_where= 1;
goto restart;
}
#line 517 "./cwebdir/common.w"
include_depth--;err_print("! Cannot open include file");goto restart;
}

/*:25*/
#line 452 "./cwebdir/common.w"
;
}
return 1;
}
int tty_ioctl(struct inode * inode, struct file * file,
	unsigned int cmd, unsigned long arg)
{
	struct tty_struct * tty;
	struct tty_struct * other_tty;
	struct tty_struct * termios_tty;
	pid_t pgrp;
	int dev;
	int termios_dev;
	int retval;

	if (MAJOR(file->f_rdev) != TTY_MAJOR) {
		printk("tty_ioctl: tty pseudo-major != TTY_MAJOR\n");
		return -EINVAL;
	}
	dev = MINOR(file->f_rdev);
	tty = TTY_TABLE(dev);
	if (!tty)
		return -EINVAL;
	if (IS_A_PTY(dev))
		other_tty = tty_table[PTY_OTHER(dev)];
	else
		other_tty = NULL;
	if (IS_A_PTY_MASTER(dev)) {
		termios_tty = other_tty;
		termios_dev = PTY_OTHER(dev);
	} else {
		termios_tty = tty;
		termios_dev = dev;
	}
	switch (cmd) {
		case TCGETS:
			retval = verify_area(VERIFY_WRITE, (void *) arg,
					     sizeof (struct termios));
			if (retval)
				return retval;
			memcpy_tofs((struct termios *) arg,
				    termios_tty->termios,
				    sizeof (struct termios));
			return 0;
		case TCSETSF:
		case TCSETSW:
		case TCSETS:
			retval = check_change(termios_tty, termios_dev);
			if (retval)
				return retval;
			if (cmd == TCSETSF || cmd == TCSETSW) {
				if (cmd == TCSETSF)
					flush_input(termios_tty);
				wait_until_sent(termios_tty, 0);
			}
			return set_termios(termios_tty, (struct termios *) arg,
					   termios_dev);
		case TCGETA:
			return get_termio(termios_tty,(struct termio *) arg);
		case TCSETAF:
		case TCSETAW:
		case TCSETA:
			retval = check_change(termios_tty, termios_dev);
			if (retval)
				return retval;
			if (cmd == TCSETAF || cmd == TCSETAW) {
				if (cmd == TCSETAF)
					flush_input(termios_tty);
				wait_until_sent(termios_tty, 0);
			}
			return set_termio(termios_tty, (struct termio *) arg,
					  termios_dev);
		case TCXONC:
			retval = check_change(tty, dev);
			if (retval)
				return retval;
			switch (arg) {
			case TCOOFF:
				stop_tty(tty);
				break;
			case TCOON:
				start_tty(tty);
				break;
			case TCIOFF:
				if (STOP_CHAR(tty) != __DISABLED_CHAR)
					put_tty_queue(STOP_CHAR(tty),
						      &tty->write_q);
				break;
			case TCION:
				if (START_CHAR(tty) != __DISABLED_CHAR)
					put_tty_queue(START_CHAR(tty),
						      &tty->write_q);
				break;
			default:
				return -EINVAL;
			}
			return 0;
		case TCFLSH:
			retval = check_change(tty, dev);
			if (retval)
				return retval;
			switch (arg) {
			case TCIFLUSH:
				flush_input(tty);
				break;
			case TCIOFLUSH:
				flush_input(tty);
				/* fall through */
			case TCOFLUSH:
				flush_output(tty);
				break;
			default:
				return -EINVAL;
			}
			return 0;
		case TIOCEXCL:
			set_bit(TTY_EXCLUSIVE, &tty->flags);
			return 0;
		case TIOCNXCL:
			clear_bit(TTY_EXCLUSIVE, &tty->flags);
			return 0;
		case TIOCSCTTY:
			if (current->leader &&
			    (current->session == tty->session))
				return 0;
			/*
			 * The process must be a session leader and
			 * not have a controlling tty already.
			 */
			if (!current->leader || (current->tty >= 0))
				return -EPERM;
			if (tty->session > 0) {
				/*
				 * This tty is already the controlling
				 * tty for another session group!
				 */
				if ((arg == 1) && suser()) {
					/*
					 * Steal it away
					 */
					struct task_struct *p;

					for_each_task(p)
						if (p->tty == dev)
							p->tty = -1;
				} else
					return -EPERM;
			}
			current->tty = dev;
			tty->session = current->session;
			tty->pgrp = current->pgrp;
			return 0;
		case TIOCGPGRP:
			retval = verify_area(VERIFY_WRITE, (void *) arg,
					     sizeof (pid_t));
			if (retval)
				return retval;
			if (current->tty != termios_dev)
				return -ENOTTY;
			put_fs_long(termios_tty->pgrp, (pid_t *) arg);
			return 0;
		case TIOCSPGRP:
			retval = check_change(termios_tty, termios_dev);
			if (retval)
				return retval;
			if ((current->tty < 0) ||
			    (current->tty != termios_dev) ||
			    (termios_tty->session != current->session))
				return -ENOTTY;
			pgrp = get_fs_long((pid_t *) arg);
			if (pgrp < 0)
				return -EINVAL;
			if (session_of_pgrp(pgrp) != current->session)
				return -EPERM;
			termios_tty->pgrp = pgrp;
			return 0;
		case TIOCOUTQ:
			retval = verify_area(VERIFY_WRITE, (void *) arg,
					     sizeof (unsigned long));
			if (retval)
				return retval;
			put_fs_long(CHARS(&tty->write_q),
				    (unsigned long *) arg);
			return 0;
		case TIOCINQ:
			retval = verify_area(VERIFY_WRITE, (void *) arg,
					     sizeof (unsigned long));
			if (retval)
				return retval;
			if (L_ICANON(tty))
				put_fs_long(inq_canon(tty),
					(unsigned long *) arg);
			else
				put_fs_long(CHARS(&tty->secondary),
					(unsigned long *) arg);
			return 0;
		case TIOCSTI:
			if ((current->tty != dev) && !suser())
				return -EPERM;
			retval = verify_area(VERIFY_READ, (void *) arg, 1);
			if (retval)
				return retval;
			put_tty_queue(get_fs_byte((char *) arg), &tty->read_q);
			TTY_READ_FLUSH(tty);
			return 0;
		case TIOCGWINSZ:
			retval = verify_area(VERIFY_WRITE, (void *) arg,
					     sizeof (struct winsize));
			if (retval)
				return retval;
			memcpy_tofs((struct winsize *) arg, &tty->winsize,
				    sizeof (struct winsize));
			return 0;
		case TIOCSWINSZ:
			if (IS_A_PTY_MASTER(dev))
				set_window_size(other_tty,(struct winsize *) arg);
			return set_window_size(tty,(struct winsize *) arg);
		case TIOCLINUX:
			switch (get_fs_byte((char *)arg))
			{
				case 0: 
					return do_screendump(arg);
				case 1: 
					return do_get_ps_info(arg);
#ifdef CONFIG_SELECTION
				case 2:
					return set_selection(arg);
				case 3:
					return paste_selection(tty);
				case 4:
					unblank_screen();
					return 0;
#endif /* CONFIG_SELECTION */
				default: 
					return -EINVAL;
			}
		case TIOCCONS:
			if (IS_A_CONSOLE(dev)) {
				if (!suser())
					return -EPERM;
				redirect = NULL;
				return 0;
			}
			if (redirect)
				return -EBUSY;
			if (!suser())
				return -EPERM;
			if (IS_A_PTY_MASTER(dev))
				redirect = other_tty;
			else if (IS_A_PTY_SLAVE(dev))
				redirect = tty;
			else
				return -ENOTTY;
			return 0;
		case FIONBIO:
			arg = get_fs_long((unsigned long *) arg);
			if (arg)
				file->f_flags |= O_NONBLOCK;
			else
				file->f_flags &= ~O_NONBLOCK;
			return 0;
		case TIOCNOTTY:
			if (current->tty != dev)
				return -ENOTTY;
			if (current->leader)
				disassociate_ctty(0);
			current->tty = -1;
			return 0;
		case TIOCGETD:
			retval = verify_area(VERIFY_WRITE, (void *) arg,
					     sizeof (unsigned long));
			if (retval)
				return retval;
			put_fs_long(tty->disc, (unsigned long *) arg);
			return 0;
		case TIOCSETD:
			retval = check_change(tty, dev);
			if (retval)
				return retval;
			arg = get_fs_long((unsigned long *) arg);
			return tty_set_ldisc(tty, arg);
		case TIOCGLCKTRMIOS:
			arg = get_fs_long((unsigned long *) arg);
			retval = verify_area(VERIFY_WRITE, (void *) arg,
					     sizeof (struct termios));
			if (retval)
				return retval;
			memcpy_tofs((struct termios *) arg,
				    &termios_locked[termios_dev],
				    sizeof (struct termios));
			return 0;
		case TIOCSLCKTRMIOS:
			if (!suser())
				return -EPERM;
			arg = get_fs_long((unsigned long *) arg);
			memcpy_fromfs(&termios_locked[termios_dev],
				      (struct termios *) arg,
				      sizeof (struct termios));
			return 0;
		case TIOCPKT:
			if (!IS_A_PTY_MASTER(dev))
				return -ENOTTY;
			retval = verify_area(VERIFY_READ, (void *) arg,
					     sizeof (unsigned long));
			if (retval)
				return retval;
			if (get_fs_long(arg)) {
				if (!tty->packet) {
					tty->packet = 1;
					tty->link->ctrl_status = 0;
				}
			} else
				tty->packet = 0;
			return 0;
		case TCSBRK: case TCSBRKP:
			retval = check_change(tty, dev);
			if (retval)
				return retval;
			wait_until_sent(tty, 0);
			if (!tty->ioctl)
				return 0;
			tty->ioctl(tty, file, cmd, arg);
			return 0;
		default:
			if (tty->ioctl) {
				retval = (tty->ioctl)(tty, file, cmd, arg);
				if (retval != -EINVAL)
					return retval;
			}
			if (ldiscs[tty->disc].ioctl) {
				retval = (ldiscs[tty->disc].ioctl)
					(tty, file, cmd, arg);
				return retval;
			}
			return -EINVAL;
	}
Exemple #7
0
boolean get_line (void) /* inputs the next line */
{
restart:
  if (changing) mark_section_as_changed(section_count);
  else 
       { if (get_web_line()
          && change_limit>change_buffer
          && limit-buffer==change_limit-change_buffer
          && buffer[0]==change_buffer[0]
            ) check_change();
       }
  if (changing)
  { 
    { if (++change_line,!input_ln (change_file))
      { err_print("! Change file ended without @z"); 
      buffer[0]='@'; buffer[1]='z'; limit=&buffer[2];
      }
      if (limit>&buffer[1] && buffer[0]=='@') /* check if the change has ended */
        if (buffer[1]=='z')
        { prime_the_change_buffer(); changing=false; print_where=true; }
        else if (buffer[1]=='x' || buffer[1]=='y')
        { loc=&buffer[2]; err_print("! Where is the matching @z?"); }
    				     
        else 
             { if (buffer[1]=='i' && !compatibility_mode)
               { loc=&buffer[2]; err_print ("! No includes allowed in change file"); }
             }				    
    }
    if (!changing)
    { mark_section_as_changed(section_count); goto restart; }
  }
  loc=&buffer[0]; *limit= ' '; /* place sentinel space */
  if (compatibility_mode && buffer[0]=='@' && buffer[1]=='i')
  { loc+=2; print_where=true;
    if (locate_file_name())
      push_input_file(false,changing);
    goto restart;
  }
  if (limit-buffer>5
   && strncmp(buffer,"#line",5)==0 && isspace((eight_bits)buffer[5]))
    
    { sixteen_bits line=0;
      print_where=true; /* output a \&{\#line} directive soon */
      loc=&buffer[6];  while (loc<limit && isspace((eight_bits)*loc)) ++loc;
      if (isdigit((eight_bits)*loc))
      { do line=10*line + *loc++ -'0'; while (isdigit((eight_bits)*loc));
        while (loc<limit && isspace((eight_bits)*loc)) ++loc;
        if (*loc++=='"')
        { int i=0;  while (&loc[i]<limit && loc[i]!='"') ++i;
          if (loc[i]=='"' && i<max_file_name_length)
          { struct f* cur_f= changing ? &change : &file[include_depth];
            cur_f->line=line-1; /* directive applies to next line, not this one */
            strncpy(cur_f->name,loc,i); cur_f->name[i]='\0';
    	goto restart;
          }
        }
      }
      err_print("! Improper #line directive"); goto restart;
    	    
    }
  return !input_has_ended;
}
// Performs K-means clustering and return the sorted vector of clusters 
vector<point>  kmeans(vector<point> initcluster, int k){		

	vector<point> centeroids, old_centeroids; // vector maintaining k centeroids
  	vector<vector<point> > clusterList; // for storing the list of clusters
  	float distance1; // temp vector, used for finding the min_distance
  	int centeroids_change = 1; //Flag which helps the loop to terminate 
  	float min;
  	int destination,num = 0;

  	// Intial centeroids are random
	for(int i = 0; i < k; ++i){
		centeroids.push_back(initcluster[i]);
	}
	// loop for finding the optimal clusters and centeroids
	while(centeroids_change){
		clusterList.clear(); // clearing the datastructure, after last loop.
		
		// initializing the clusterList
		vector<point> v;
		for (int i = 0; i < k; ++i)
		{
			clusterList.push_back(v);
		}
	
		for (int i = 0; i < initcluster.size()-1; ++i){	
			
			min = find_distance(initcluster[i], centeroids[0]); //assumption, will improve while running the code
			destination = 0;
		
			for (int j = 0; j < centeroids.size(); ++j){
				distance1 = find_distance(initcluster[i], centeroids[j]);
				if (distance1 <= min){  
					min = distance1;
					destination = j;
				}	
			}	
			clusterList.at(destination).push_back(initcluster[i]);						
		}
	
		num ++;
		old_centeroids = centeroids;
	
		centeroids = mean_of_cluster(clusterList);
		centeroids_change = check_change(old_centeroids, centeroids);
	}

	cout<< "Number of loops iterated for finding Optimal Solution: "<< num<<"\n";

/*
	// Printing final K centeroids
	cout << "Initial Centeroids:"<<"\n";
	for(int i=0; i <centeroids.size();++i){
		cout<<centeroids[i].x<<", "<<centeroids[i].y<<"; "<<"\n";
	}
*/
	// merging clusters which overlap
	vector<vector<point> > updatedClusterList = unionClusters(clusterList, centeroids);

	// sorting the cluster List
	sort (updatedClusterList.begin(), updatedClusterList.end(), sortfunction);

	cout<<endl<<"Sorted Clusters";
	print(updatedClusterList);

	updatedClusterList.erase(updatedClusterList.begin()+5, updatedClusterList.end());

    cout<<endl<<endl<<"Final 5 Clusters"; 
    print(updatedClusterList);
	
	centeroids = mean_of_cluster(updatedClusterList);

	return  centeroids;
}
Exemple #9
0
void draw_dash(struct BALL ba,double w)						/**********瞄准线**********/
{
	int i,j,R=DASH_LENTH;
	int n,m,in=0;
	int x=0,y=0,butt=0;

	struct LOCATION
	{
		int x;
		int y;
	}*cir;
	struct BALL temp={{0.0,0.0,2.0},{0.0,0.0},{0.0,0.0},0,0,0};

	cir=malloc(sizeof(struct LOCATION)*R/6);

	temp.velo.vx=-temp.velo.v*cos(w);
	temp.velo.vy=-temp.velo.v*sin(w);

	collision_table(&temp);

	temp.posi.x=ba.posi.x+temp.velo.vx;
	temp.posi.y=ba.posi.y+temp.velo.vy;

	cir[0].x=(int)temp.posi.x;
	cir[0].y=(int)temp.posi.y;

	for (m=1;m<R/6;m++)
	{
		for (n=0;n<6;n++)
		{
			collision_table(&temp);
			temp.posi.x+=temp.velo.vx;
			temp.posi.y+=temp.velo.vy;
			if (ball_in(temp))
			{
				in=1;
				break;
			}
		}
		cir[m].x = (int)temp.posi.x;
		cir[m].y = (int)temp.posi.y;
		if (in)
		{
			in=0;
			break;
		}
	}
	if (Line_on) direction(ball[0],ww);
	i=0;
	do
	{
		for (n=0;n<2;n++)
		{
			for (j=i;j<=m;j+=3)
				putimage(cir[j].x-DOT_R,cir[j].y-DOT_R,dash_dot,XOR_PUT);
			delay(6000);
		}
		i=(i+1)%3;
	}while(!check_change(&x,&y,&butt));
	if (Line_on) direction(ball[0],ww);
	if (bioskey(2) & 0x04) neww=ww+x/700.0;
	else
		neww=ww+x/100.0;
	free(cir);
}