Exemplo n.º 1
0
        public void StopRecording()
        {
            m_bIsRecording = false;
            log.Debug("Stop recording images to file.");

            if (m_VideoRecorder != null)
            {
                // Add a VideofileBox with a thumbnail of this video.
                if (m_VideoRecorder.CaptureThumb != null)
                {
                    CapturedVideo cv = new CapturedVideo(m_CurrentCaptureFilePath, m_VideoRecorder.CaptureThumb);
                    m_RecentlyCapturedVideos.Add(cv);
                    m_VideoRecorder.CaptureThumb.Dispose();
                    m_Container.DoUpdateCapturedVideos();
                }

                // Terminate the recording thread and release resources. This will treat any outstanding frames in the queue.
                m_VideoRecorder.Dispose();
            }

            Thread.CurrentThread.Priority = ThreadPriority.Normal;

            // Ask the Explorer tree to refresh itself, (but not the thumbnails pane.)
            DelegatesPool dp = DelegatesPool.Instance();

            if (dp.RefreshFileExplorer != null)
            {
                dp.RefreshFileExplorer(false);
            }
        }
Exemplo n.º 2
0
        public void SetEditMode(bool _bEdit, CoordinateSystem _transformer)
        {
            m_bEditMode = _bEdit;

            if (m_CoordinateSystem == null)
            {
                m_CoordinateSystem = _transformer;
            }

            // Activate or deactivate the ScreenManager Keyboard Handler,
            // so we can use <space>, <return>, etc.
            DelegatesPool dp = DelegatesPool.Instance();

            if (m_bEditMode)
            {
                if (dp.DeactivateKeyboardHandler != null)
                {
                    dp.DeactivateKeyboardHandler();
                }

                RelocateEditbox(); // This is needed because the container top-left corner may have changed
            }
            else
            {
                if (dp.ActivateKeyboardHandler != null)
                {
                    dp.ActivateKeyboardHandler();
                }
            }

            m_TextBox.Visible = m_bEditMode;
        }
Exemplo n.º 3
0
        public FileBrowserUserInterface()
        {
            InitializeComponent();
            Dock = DockStyle.Fill;
            btnAddShortcut.Parent    = lblFavFolders;
            btnDeleteShortcut.Parent = lblFavFolders;

            // Drag Drop handling.
            lvExplorer.ItemDrag  += lv_ItemDrag;
            lvShortcuts.ItemDrag += lv_ItemDrag;
            etExplorer.AllowDrop  = false;
            etShortcuts.AllowDrop = false;

            BuildContextMenu();

            // Registers our exposed functions to the DelegatePool.
            var dp = DelegatesPool.Instance();

            dp.RefreshFileExplorer = DoRefreshFileList;

            // Take the list of shortcuts from the prefs and load them.
            ReloadShortcuts();

            // Reload last tab from prefs.
            // We don't reload the splitters here, because we are not at full size yet and they are anchored.
            tabControl.SelectedIndex = (int)_mPreferencesManager.ActiveTab;

            Application.Idle += IdleDetector;
        }
Exemplo n.º 4
0
        private void mnuDelete_Click(object sender, EventArgs e)
        {
            // Use the built-in dialogs to confirm (or not).
            // Delete is done through moving to recycle bin.
            if (File.Exists(m_CapturedVideo.Filepath))
            {
                try
                {
                    FileSystem.DeleteFile(m_CapturedVideo.Filepath, UIOption.AllDialogs, RecycleOption.SendToRecycleBin);
                }
                catch (OperationCanceledException)
                {
                    // User cancelled confirmation box.
                }

                // Other possible error case: the file couldn't be deleted because it's still in use.

                // If file was effectively moved to trash, hide the thumb and reload the folder.
                if (!File.Exists(m_CapturedVideo.Filepath))
                {
                    if (CloseThumb != null)
                    {
                        CloseThumb(this, e);
                    }

                    // Ask the Explorer tree to refresh itself...
                    // This will in turn refresh the thumbnails pane.
                    DelegatesPool dp = DelegatesPool.Instance();
                    if (dp.RefreshFileExplorer != null)
                    {
                        dp.RefreshFileExplorer(true);
                    }
                }
            }
        }
        public FileBrowserUserInterface()
        {
            InitializeComponent();
            this.Dock                = DockStyle.Fill;
            btnAddShortcut.Parent    = lblFavFolders;
            btnDeleteShortcut.Parent = lblFavFolders;

            // Drag Drop handling.
            lvExplorer.ItemDrag  += new ItemDragEventHandler(lv_ItemDrag);
            lvShortcuts.ItemDrag += new ItemDragEventHandler(lv_ItemDrag);
            etExplorer.AllowDrop  = false;
            etShortcuts.AllowDrop = false;

            BuildContextMenu();

            // Associate with the system icons for files... Is this really needed ?
            //ExpTreeLib.SystemImageListManager.SetListViewImageList(lvExplorer, false, false);
            //ExpTreeLib.SystemImageListManager.SetListViewImageList(lvShortcuts, false, false);

            // Registers our exposed functions to the DelegatePool.
            DelegatesPool dp = DelegatesPool.Instance();

            dp.RefreshFileExplorer = DoRefreshFileList;

            // Take the list of shortcuts from the prefs and load them.
            ReloadShortcuts();

            // Reload last tab from prefs.
            // We don't reload the splitters here, because we are not at full size yet and they are anchored.
            tabControl.SelectedIndex = (int)m_PreferencesManager.ActiveTab;

            Application.Idle += new EventHandler(this.IdleDetector);
        }
Exemplo n.º 6
0
        private void mnuDelete_Click(object sender, EventArgs e)
        {
            // Use the built-in dialogs to confirm (or not).
            // Delete is done through moving to recycle bin.
            try
            {
                FileSystem.DeleteFile(m_FileName, UIOption.AllDialogs, RecycleOption.SendToRecycleBin);
            }
            catch (OperationCanceledException)
            {
                // User cancelled confirmation box.
            }

            // If file was effectively moved to trash, reload the folder.
            if (!File.Exists(m_FileName))
            {
                // Ask the Explorer tree to refresh itself...
                // This will in turn refresh the thumbnails pane.
                DelegatesPool dp = DelegatesPool.Instance();
                if (dp.RefreshFileExplorer != null)
                {
                    dp.RefreshFileExplorer(true);
                }
            }
        }
Exemplo n.º 7
0
        private void mnuPreferencesOnClick(object sender, EventArgs e)
        {
            DelegatesPool dp = DelegatesPool.Instance();

            if (dp.StopPlaying != null && dp.DeactivateKeyboardHandler != null)
            {
                dp.StopPlaying();
                dp.DeactivateKeyboardHandler();
            }

            FormPreferences2 fp = new FormPreferences2(-1);

            fp.ShowDialog();
            fp.Dispose();

            if (dp.ActivateKeyboardHandler != null)
            {
                dp.ActivateKeyboardHandler();
            }

            // Refresh Preferences
            PreferencesManager pm = PreferencesManager.Instance();

            log.Debug("Setting current ui culture.");
            Thread.CurrentThread.CurrentUICulture = pm.GetSupportedCulture();
            RefreshUICulture();
        }
Exemplo n.º 8
0
        private void mnuSealMeasure_Click(object sender, EventArgs e)
        {
            // display a dialog that let the user specify how many real-world-units long is this line.

            if (m_StartPoint.X != m_EndPoint.X || m_StartPoint.Y != m_EndPoint.Y)
            {
                if (!m_bShowMeasure)
                {
                    m_bShowMeasure = true;
                }

                DrawingToolLine2D.ShowMeasure = true;

                DelegatesPool dp = DelegatesPool.Instance();
                if (dp.DeactivateKeyboardHandler != null)
                {
                    dp.DeactivateKeyboardHandler();
                }

                formConfigureMeasure fcm = new formConfigureMeasure(m_ParentMetadata, this);
                ScreenManagerKernel.LocateForm(fcm);
                fcm.ShowDialog();
                fcm.Dispose();

                // Update traj for distance and speed after calibration.
                m_ParentMetadata.UpdateTrajectoriesForKeyframes();

                CallInvalidateFromMenu(sender);

                if (dp.ActivateKeyboardHandler != null)
                {
                    dp.ActivateKeyboardHandler();
                }
            }
        }
Exemplo n.º 9
0
        private void mnuCheckForUpdatesOnClick(object sender, EventArgs e)
        {
            // Stop playing if needed.
            DelegatesPool dp = DelegatesPool.Instance();

            if (dp.StopPlaying != null)
            {
                dp.StopPlaying();
            }

            // Download the update configuration file from the webserver.
            HelpIndex hiRemote;

            if (PreferencesManager.ExperimentalRelease)
            {
                hiRemote = new HelpIndex("http://www.kinovea.org/setup/updatebeta.xml");
            }
            else
            {
                hiRemote = new HelpIndex("http://www.kinovea.org/setup/update.xml");
            }

            if (hiRemote.LoadSuccess)
            {
                if (dp.DeactivateKeyboardHandler != null)
                {
                    dp.DeactivateKeyboardHandler();
                }

                // Check if we are up to date.
                ThreePartsVersion currentVersion = new ThreePartsVersion(PreferencesManager.ReleaseVersion);
                if (hiRemote.AppInfos.Version > currentVersion)
                {
                    // We are not up to date, display the full dialog.
                    // The dialog is responsible for displaying the download success msg box.
                    UpdateDialog2 ud = new UpdateDialog2(hiRemote);
                    ud.ShowDialog();
                    ud.Dispose();
                }
                else
                {
                    // We are up to date, display a simple confirmation box.
                    MessageBox.Show(UpdaterLang.Updater_UpToDate, UpdaterLang.Updater_Title,
                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                }

                if (dp.ActivateKeyboardHandler != null)
                {
                    dp.ActivateKeyboardHandler();
                }
            }
            else
            {
                // Remote connection failed, we are probably firewalled.
                MessageBox.Show(resManager.GetString("Updater_InternetError", Thread.CurrentThread.CurrentUICulture),
                                resManager.GetString("Updater_Title", Thread.CurrentThread.CurrentUICulture),
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Exclamation);
            }
        }
Exemplo n.º 10
0
        private void ScreenManagerUserInterface_DoubleClick(object sender, EventArgs e)
        {
            DelegatesPool dp = DelegatesPool.Instance();

            if (dp.OpenVideoFile != null)
            {
                dp.OpenVideoFile();
            }
        }
Exemplo n.º 11
0
        protected void ProcessingOver(DrawtimeFilterOutput _dfo)
        {
            // Notify the ScreenManager that we are done.
            DelegatesPool dp = DelegatesPool.Instance();

            if (dp.VideoProcessingDone != null)
            {
                dp.VideoProcessingDone(_dfo);
            }
        }
Exemplo n.º 12
0
        public void AfterSave()
        {
            // Ask the Explorer tree to refresh itself, (but not the thumbnails pane.)
            DelegatesPool dp = DelegatesPool.Instance();

            if (dp.RefreshFileExplorer != null)
            {
                dp.RefreshFileExplorer(false);
            }
        }
Exemplo n.º 13
0
        private void TbFileNameKeyPress(object sender, KeyPressEventArgs e)
        {
            // editing a file name.

            if (e.KeyChar == 13)     // Carriage Return.
            {
                string newFileName = Path.GetDirectoryName(m_FileName) + "\\" + tbFileName.Text;

                // Prevent overwriting.
                if (File.Exists(m_FileName) && !File.Exists(newFileName) && newFileName.Length > 5)
                {
                    // Try to change the filename
                    try
                    {
                        File.Move(m_FileName, newFileName);

                        // If renaming went fine, consolidate the file name.
                        if (!File.Exists(m_FileName))
                        {
                            FileName = newFileName;
                        }

                        // Ask the Explorer tree to refresh itself...
                        // But not the thumbnails pane.
                        DelegatesPool dp = DelegatesPool.Instance();
                        if (dp.RefreshFileExplorer != null)
                        {
                            dp.RefreshFileExplorer(false);
                        }
                    }
                    catch (ArgumentException)
                    {
                        // contains only white space, or contains invalid characters as defined in InvalidPathChars.
                        // -> Silently fail.
                        // TODO:Display error dialog box.
                    }
                    catch (UnauthorizedAccessException)
                    {
                        // The caller does not have the required permission.
                    }
                    catch (Exception)
                    {
                        // Log error.
                    }
                }
                QuitEditMode();

                // Set this thumb as selected.
                SetSelected();
            }
            else if (e.KeyChar == 27)    // Escape.
            {
                QuitEditMode();
            }
        }
Exemplo n.º 14
0
        private void UpdateFileList(CShItem folder, ListView listView, bool bRefreshThumbnails)
        {
            // Update a file list with the given folder.
            // Triggers an update of the thumbnails pane if requested.

            Log.Debug(string.Format("Updating file list : {0}", listView.Name));

            if (folder != null)
            {
                Cursor = Cursors.WaitCursor;

                listView.BeginUpdate();
                listView.Items.Clear();

                // Each list element will store the CShItem it's referring to in its Tag property.
                // Get all files in the folder, and add them to the list.
                var fileList  = folder.GetFiles();
                var fileNames = new List <string>();
                for (var i = 0; i < fileList.Count; i++)
                {
                    var shellItem = (CShItem)fileList[i];

                    if (IsKnownFileType(Path.GetExtension(shellItem.Path)))
                    {
                        var lvi = new ListViewItem(shellItem.DisplayName);

                        lvi.Tag = shellItem;
                        //lvi.ImageIndex = ExpTreeLib.SystemImageListManager.GetIconIndex(ref shellItem, false, false);
                        lvi.ImageIndex = 6;

                        listView.Items.Add(lvi);

                        fileNames.Add(shellItem.Path);
                    }
                }

                listView.EndUpdate();
                Log.Debug("List updated");

                // Even if we don't want to reload the thumbnails, we must ensure that
                // the screen manager backup list is in sync with the actual file list.
                // desync can happen in case of renaming and deleting files.
                // the screenmanager backup list is used at BringBackThumbnail,
                // (i.e. when we close a screen)
                var dp = DelegatesPool.Instance();
                if (dp.DisplayThumbnails != null)
                {
                    Log.Debug("Asking the ScreenManager to refresh the thumbnails.");
                    dp.DisplayThumbnails(fileNames, bRefreshThumbnails);
                }

                Cursor = Cursors.Default;
            }
        }
Exemplo n.º 15
0
        private void DeactivateKeyboardHandler()
        {
            // Mouse enters the info box : deactivate the keyboard handling for the screens
            // so we can use <space>, <return>, etc. here.
            DelegatesPool dp = DelegatesPool.Instance();

            if (dp.DeactivateKeyboardHandler != null)
            {
                dp.DeactivateKeyboardHandler();
            }
        }
Exemplo n.º 16
0
        private void ActivateKeyboardHandler()
        {
            // Mouse leave the box : reactivate the keyboard handling for the screens
            // so we can use <space>, <return>, etc. as player shortcuts
            DelegatesPool dp = DelegatesPool.Instance();

            if (dp.ActivateKeyboardHandler != null)
            {
                dp.ActivateKeyboardHandler();
            }
        }
Exemplo n.º 17
0
        /// <summary>
        /// Command execution.
        /// Load the given file in the given screen.
        /// </summary>
        public void Execute()
        {
            DelegatesPool dp = DelegatesPool.Instance();

            if (dp.StopPlaying != null)
            {
                dp.StopPlaying();
            }

            DirectLoad();
        }
Exemplo n.º 18
0
        private void ActivateKeyboardHandler()
        {
            // Mouse leave the info box : reactivate the keyboard handling for the screens
            // so we can use <space>, <return>, etc. as player shortcuts.
            // This is sometimes strange. You put the mouse away to start typing,
            // and the first carriage return triggers the playback leaving the key image.

            DelegatesPool dp = DelegatesPool.Instance();

            if (dp.ActivateKeyboardHandler != null)
            {
                dp.ActivateKeyboardHandler();
            }
        }
Exemplo n.º 19
0
        public SupervisorUserInterface(RootKernel _RootKernel)
        {
            RootKernel = _RootKernel;
            InitializeComponent();
            m_bInitialized = false;

            // Get Explorer values from settings.
            m_PrefManager          = PreferencesManager.Instance();
            m_iOldSplitterDistance = m_PrefManager.ExplorerSplitterDistance;

            // Services offered here
            DelegatesPool dp = DelegatesPool.Instance();

            dp.OpenVideoFile = DoOpenVideoFile;
        }
Exemplo n.º 20
0
        private void mnuOpenFileOnClick(object sender, EventArgs e)
        {
            DelegatesPool dp = DelegatesPool.Instance();

            if (dp.StopPlaying != null)
            {
                dp.StopPlaying();
            }

            string filePath = LaunchOpenFileDialog();

            if (filePath.Length > 0)
            {
                OpenFileFromPath(filePath);
            }
        }
Exemplo n.º 21
0
        public RootKernel()
        {
            // Store Kinovea's version from the assembly.
            Version v = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;

            PreferencesManager.ReleaseVersion = String.Format("{0}.{1}.{2}", v.Major, v.Minor, v.Build);

            // Set type of release (Experimental vs Production)
            PreferencesManager.ExperimentalRelease = true;

            // Display some system infos in the log.
            log.Info(String.Format("Kinovea version : {0}, ({1})", PreferencesManager.ReleaseVersion, PreferencesManager.ExperimentalRelease?"Experimental":"Production"));
            log.Info(".NET Framework Version : " + Environment.Version.ToString());
            log.Info("OS Version : " + System.Environment.OSVersion.ToString());
            log.Info("Primary Screen : " + SystemInformation.PrimaryMonitorSize.ToString());
            log.Info("Virtual Screen : " + SystemInformation.VirtualScreen.ToString());

            // Since it is the very first call, it will both instanciate and import.
            // Previous calls were done on static prioperties, no instanciation.
            PreferencesManager pm = PreferencesManager.Instance();

            // Initialise command line parser and get the arguments.
            CommandLineArgumentManager am = CommandLineArgumentManager.Instance();

            am.InitializeCommandLineParser();
            string[] args = Environment.GetCommandLineArgs();
            am.ParseArguments(args);

            BuildSubTree();
            MainWindow = new KinoveaMainWindow(this);

            log.Debug("Plug sub modules at UI extension points (Menus, ToolBars, StatusBAr, Windows).");
            ExtendMenu(MainWindow.menuStrip);
            ExtendToolBar(MainWindow.toolStrip);
            ExtendStatusBar(MainWindow.statusStrip);
            ExtendUI();

            log.Debug("Register global services offered at Root level.");
            DelegatesPool dp = DelegatesPool.Instance();

            dp.UpdateStatusBar = DoUpdateStatusBar;
            dp.MakeTopMost     = DoMakeTopMost;
        }
Exemplo n.º 22
0
        public void DoOpenVideoFile()
        {
            // Open a video.
            if ((RootKernel.ScreenManager.screenList.Count == 0) && (!isOpening))
            {
                isOpening = true;

                string filePath = RootKernel.LaunchOpenFileDialog();
                if (filePath.Length > 0)
                {
                    DelegatesPool dp = DelegatesPool.Instance();
                    if (dp.LoadMovieInScreen != null)
                    {
                        dp.LoadMovieInScreen(filePath, -1, true);
                    }
                }

                isOpening = false;
            }
        }
Exemplo n.º 23
0
        public ScreenManagerUserInterface(IScreenManagerUIContainer _ScreenManagerUIContainer)
        {
            log.Debug("Constructing ScreenManagerUserInterface.");

            m_ScreenManagerUIContainer = _ScreenManagerUIContainer;

            InitializeComponent();
            ComCtrls.ScreenManagerUIContainer = m_ScreenManagerUIContainer;
            m_ThumbsViewer.SetScreenManagerUIContainer(m_ScreenManagerUIContainer);

            BackColor = Color.White;
            Dock      = DockStyle.Fill;

            m_ThumbsViewer.Top      = 0;
            m_ThumbsViewer.Left     = 0;
            m_ThumbsViewer.Width    = Width;
            m_ThumbsViewer.Height   = Height - pbLogo.Height - 10;
            m_ThumbsViewer.Anchor   = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom;
            m_ThumbsViewer.Closing += ThumbsViewer_Closing;
            this.Controls.Add(m_ThumbsViewer);

            m_DelegateUpdateTrkFrame = new DelegateUpdateTrkFrame(UpdateTrkFrame);

            // Registers our exposed functions to the DelegatePool.
            DelegatesPool dp = DelegatesPool.Instance();

            dp.DisplayThumbnails = DoDisplayThumbnails;

            // Thumbs are enabled by default.
            m_ThumbsViewer.Visible   = true;
            m_bThumbnailsWereVisible = true;
            m_ThumbsViewer.BringToFront();

            pnlScreens.BringToFront();
            pnlScreens.Dock = DockStyle.Fill;

            Application.Idle += new EventHandler(this.IdleDetector);
        }
Exemplo n.º 24
0
        private void LaunchItemAt(ListView listView, MouseEventArgs e)
        {
            // Launch the video.

            var lvi = listView.GetItemAt(e.X, e.Y);

            if (lvi != null && listView.SelectedItems != null && listView.SelectedItems.Count == 1)
            {
                var item = listView.SelectedItems[0].Tag as CShItem;

                if (item != null)
                {
                    if (item.IsFileSystem)
                    {
                        var dp = DelegatesPool.Instance();
                        if (dp.LoadMovieInScreen != null)
                        {
                            dp.LoadMovieInScreen(item.Path, -1, true);
                        }
                    }
                }
            }
        }
Exemplo n.º 25
0
		public override void PromptDeviceSelector()
		{
			DelegatesPool dp = DelegatesPool.Instance();
			if (dp.DeactivateKeyboardHandler != null)
            {
                dp.DeactivateKeyboardHandler();
			}
			
			bool reconnected = false;
			
			// Ask the user which device he wants to use or which size/framerate.
			formDevicePicker fdp = new formDevicePicker(ListDevices(), m_CurrentVideoDevice, DisplayDevicePropertyPage);
			
			if(fdp.ShowDialog() == DialogResult.OK)
			{
				DeviceDescriptor dev = fdp.SelectedDevice;
				
				if(dev == null || dev.Empty)
				{
					log.DebugFormat("Selected device is null or empty.");
					if(m_CurrentVideoDevice != null)
					{
						// From something to empty.
						Disconnect();
					}
				}
				else if(dev.Network)
				{
					if(m_CurrentVideoDevice == null || !m_CurrentVideoDevice.Network)
					{
						// From empty or non-network to network.
						log.DebugFormat("Selected network camera - connect with default parameters");
						reconnected = ConnectToDevice(dev);	
					}
					else
					{
						// From network to network.
						log.DebugFormat("Network camera - parameters changed - connect with new parameters");
						// Parameters were set on the dialog. We don't care if the parameters were actually changed.
						DeviceDescriptor netDevice = new DeviceDescriptor(ScreenManagerLang.Capture_NetworkCamera, fdp.SelectedUrl, fdp.SelectedFormat);
						reconnected = ConnectToDevice(netDevice);
					}
				} 
				else
				{
					if(m_CurrentVideoDevice == null || m_CurrentVideoDevice.Network || dev.Identification != m_CurrentVideoDevice.Identification)
					{
						// From network or different capture device to capture device.
						log.DebugFormat("Selected capture device");
						reconnected = ConnectToDevice(dev);
					}
					else
					{
						// From same capture device - caps changed.
						DeviceCapability cap = fdp.SelectedCapability;
						if(cap != null && !cap.Equals(m_CurrentVideoDevice.SelectedCapability))
						{							
							log.DebugFormat("Capture device, capability changed.");
							
							m_CurrentVideoDevice.SelectedCapability = cap;
							//PreferencesManager.CapturePreferences.UpdateDeviceConfiguration(m_CurrentVideoDevice.Identification, cap);
							//PreferencesManager.Save();
							
							if(m_bIsGrabbing)
							{
								m_VideoSource.Stop();
							}
							
							((VideoCaptureDevice)m_VideoSource).DesiredFrameSize = cap.FrameSize;
							((VideoCaptureDevice)m_VideoSource).DesiredFrameRate = cap.Framerate;
							
							m_FrameSize = cap.FrameSize;
							m_FramesInterval = 1000 / (double)cap.Framerate;
				
							log.Debug(String.Format("New capability: {0}", cap.ToString()));
							
							m_bSizeChanged = true;
							
							if(m_bIsGrabbing)
							{
								m_VideoSource.Start();
							}	
						}
					}
				}
				
				if(reconnected)
					m_Container.Connected();
			}
			
			fdp.Dispose();
			
			if(dp.ActivateKeyboardHandler != null)
            {
            	dp.ActivateKeyboardHandler();
            }
		}