hunk.code_window:                 PostStore.removePendingPost(post.channel_id, post.pending_post_id);
               },
               (err) => {
                   if (err.id === 'api.post.create_post.root_id.app_error') {
  
hunk.labels: add keep keep keep
hunk.after_edit:                 AppDispatcher.handleServerAction({
                       type: ActionTypes.RECEIVED_POST,
                       post: data
                   });
  
hunk.file_path: webapp/components/create_comment.jsx
hunk.type: add
file: // Copyright 2010 The Go Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
  
  // +build freebsd openbsd netbsd dragonfly darwin
  
  package fsnotify
  
  import (
  	"errors"
  	"fmt"
  	"io/ioutil"
  	"os"
  	"path/filepath"
  	"sync"
  	"time"
  
  	"golang.org/x/sys/unix"
  )
  
  // Watcher watches a set of files, delivering events to a channel.
  type Watcher struct {
  	Events chan Event
  	Errors chan error
  	done   chan bool // Channel for sending a "quit message" to the reader goroutine
  
  	kq int // File descriptor (as returned by the kqueue() syscall).
  
  	mu              sync.Mutex        // Protects access to watcher data
  	watches         map[string]int    // Map of watched file descriptors (key: path).
  	externalWatches map[string]bool   // Map of watches added by user of the library.
  	dirFlags        map[string]uint32 // Map of watched directories to fflags used in kqueue.
  	paths           map[int]pathInfo  // Map file descriptors to path names for processing kqueue events.
  	fileExists      map[string]bool   // Keep track of if we know this file exists (to stop duplicate create events).
  	isClosed        bool              // Set to true when Close() is first called
  }
  
  type pathInfo struct {
  	name  string
  	isDir bool
  }
  
  // NewWatcher establishes a new watcher with the underlying OS and begins waiting for events.
  func NewWatcher() (*Watcher, error) {
  	kq, err := kqueue()
  	if err != nil {
  		return nil, err
  	}
  
  	w := &Watcher{
  		kq:              kq,
  		watches:         make(map[string]int),
  		dirFlags:        make(map[string]uint32),
  		paths:           make(map[int]pathInfo),
  		fileExists:      make(map[string]bool),
  		externalWatches: make(map[string]bool),
  		Events:          make(chan Event),
  		Errors:          make(chan error),
  		done:            make(chan bool),
  	}
  
  	go w.readEvents()
  	return w, nil
  }
  
  // Close removes all watches and closes the events channel.
  func (w *Watcher) Close() error {
  	w.mu.Lock()
  	if w.isClosed {
  		w.mu.Unlock()
  		return nil
  	}
  	w.isClosed = true
  	w.mu.Unlock()
  
  	// copy paths to remove while locked
  	w.mu.Lock()
  	var pathsToRemove = make([]string, 0, len(w.watches))
  	for name := range w.watches {
  		pathsToRemove = append(pathsToRemove, name)
  	}
  	w.mu.Unlock()
  	// unlock before calling Remove, which also locks
  
  	var err error
  	for _, name := range pathsToRemove {
  		if e := w.Remove(name); e != nil && err == nil {
  			err = e
  		}
  	}
  
  	// Send "quit" message to the reader goroutine:
  	w.done <- true
  
  	return nil
  }
  
  // Add starts watching the named file or directory (non-recursively).
  func (w *Watcher) Add(name string) error {
  	w.mu.Lock()
  	w.externalWatches[name] = true
  	w.mu.Unlock()
  	_, err := w.addWatch(name, noteAllEvents)
  	return err
  }
  
  // Remove stops watching the the named file or directory (non-recursively).
  func (w *Watcher) Remove(name string) error {
  	name = filepath.Clean(name)
  	w.mu.Lock()
  	watchfd, ok := w.watches[name]
  	w.mu.Unlock()
  	if !ok {
  		return fmt.Errorf("can't remove non-existent kevent watch for: %s", name)
  	}
  
  	const registerRemove = unix.EV_DELETE
  	if err := register(w.kq, []int{watchfd}, registerRemove, 0); err != nil {
  		return err
  	}
  
  	unix.Close(watchfd)
  
  	w.mu.Lock()
  	isDir := w.paths[watchfd].isDir
  	delete(w.watches, name)
  	delete(w.paths, watchfd)
  	delete(w.dirFlags, name)
  	w.mu.Unlock()
  
  	// Find all watched paths that are in this directory that are not external.
  	if isDir {
  		var pathsToRemove []string
  		w.mu.Lock()
  		for _, path := range w.paths {
  			wdir, _ := filepath.Split(path.name)
  			if filepath.Clean(wdir) == name {
  				if !w.externalWatches[path.name] {
  					pathsToRemove = append(pathsToRemove, path.name)
  				}
  			}
  		}
  		w.mu.Unlock()
  		for _, name := range pathsToRemove {
  			// Since these are internal, not much sense in propagating error
  			// to the user, as that will just confuse them with an error about
  			// a path they did not explicitly watch themselves.
  			w.Remove(name)
  		}
  	}
  
  	return nil
  }
  
  // Watch all events (except NOTE_EXTEND, NOTE_LINK, NOTE_REVOKE)
  const noteAllEvents = unix.NOTE_DELETE | unix.NOTE_WRITE | unix.NOTE_ATTRIB | unix.NOTE_RENAME
  
  // keventWaitTime to block on each read from kevent
  var keventWaitTime = durationToTimespec(100 * time.Millisecond)
  
  // addWatch adds name to the watched file set.
  // The flags are interpreted as described in kevent(2).
  // Returns the real path to the file which was added, if any, which may be different from the one passed in the case of symlinks.
  func (w *Watcher) addWatch(name string, flags uint32) (string, error) {
  	var isDir bool
  	// Make ./name and name equivalent
  	name = filepath.Clean(name)
  
  	w.mu.Lock()
  	if w.isClosed {
  		w.mu.Unlock()
  		return "", errors.New("kevent instance already closed")
  	}
  	watchfd, alreadyWatching := w.watches[name]
  	// We already have a watch, but we can still override flags.
  	if alreadyWatching {
  		isDir = w.paths[watchfd].isDir
  	}
  	w.mu.Unlock()
  
  	if !alreadyWatching {
  		fi, err := os.Lstat(name)
  		if err != nil {
  			return "", err
  		}
  
  		// Don't watch sockets.
  		if fi.Mode()&os.ModeSocket == os.ModeSocket {
  			return "", nil
  		}
  
  		// Don't watch named pipes.
  		if fi.Mode()&os.ModeNamedPipe == os.ModeNamedPipe {
  			return "", nil
  		}
  
  		// Follow Symlinks
  		// Unfortunately, Linux can add bogus symlinks to watch list without
  		// issue, and Windows can't do symlinks period (AFAIK). To  maintain
  		// consistency, we will act like everything is fine. There will simply
  		// be no file events for broken symlinks.
  		// Hence the returns of nil on errors.
  		if fi.Mode()&os.ModeSymlink == os.ModeSymlink {
  			name, err = filepath.EvalSymlinks(name)
  			if err != nil {
  				return "", nil
  			}
  
  			w.mu.Lock()
  			_, alreadyWatching = w.watches[name]
  			w.mu.Unlock()
  
  			if alreadyWatching {
  				return name, nil
  			}
  
  			fi, err = os.Lstat(name)
  			if err != nil {
  				return "", nil
  			}
  		}
  
  		watchfd, err = unix.Open(name, openMode, 0700)
  		if watchfd == -1 {
  			return "", err
  		}
  
  		isDir = fi.IsDir()
  	}
  
  	const registerAdd = unix.EV_ADD | unix.EV_CLEAR | unix.EV_ENABLE
  	if err := register(w.kq, []int{watchfd}, registerAdd, flags); err != nil {
  		unix.Close(watchfd)
  		return "", err
  	}
  
  	if !alreadyWatching {
  		w.mu.Lock()
  		w.watches[name] = watchfd
  		w.paths[watchfd] = pathInfo{name: name, isDir: isDir}
  		w.mu.Unlock()
  	}
  
  	if isDir {
  		// Watch the directory if it has not been watched before,
  		// or if it was watched before, but perhaps only a NOTE_DELETE (watchDirectoryFiles)
  		w.mu.Lock()
  
  		watchDir := (flags&unix.NOTE_WRITE) == unix.NOTE_WRITE &&
  			(!alreadyWatching || (w.dirFlags[name]&unix.NOTE_WRITE) != unix.NOTE_WRITE)
  		// Store flags so this watch can be updated later
  		w.dirFlags[name] = flags
  		w.mu.Unlock()
  
  		if watchDir {
  			if err := w.watchDirectoryFiles(name); err != nil {
  				return "", err
  			}
  		}
  	}
  	return name, nil
  }
  
  // readEvents reads from kqueue and converts the received kevents into
  // Event values that it sends down the Events channel.
  func (w *Watcher) readEvents() {
  	eventBuffer := make([]unix.Kevent_t, 10)
  
  	for {
  		// See if there is a message on the "done" channel
  		select {
  		case <-w.done:
  			err := unix.Close(w.kq)
  			if err != nil {
  				w.Errors <- err
  			}
  			close(w.Events)
  			close(w.Errors)
  			return
  		default:
  		}
  
  		// Get new events
  		kevents, err := read(w.kq, eventBuffer, &keventWaitTime)
  		// EINTR is okay, the syscall was interrupted before timeout expired.
  		if err != nil && err != unix.EINTR {
  			w.Errors <- err
  			continue
  		}
  
  		// Flush the events we received to the Events channel
  		for len(kevents) > 0 {
  			kevent := &kevents[0]
  			watchfd := int(kevent.Ident)
  			mask := uint32(kevent.Fflags)
  			w.mu.Lock()
  			path := w.paths[watchfd]
  			w.mu.Unlock()
  			event := newEvent(path.name, mask)
  
  			if path.isDir && !(event.Op&Remove == Remove) {
  				// Double check to make sure the directory exists. This can happen when
  				// we do a rm -fr on a recursively watched folders and we receive a
  				// modification event first but the folder has been deleted and later
  				// receive the delete event
  				if _, err := os.Lstat(event.Name); os.IsNotExist(err) {
  					// mark is as delete event
  					event.Op |= Remove
  				}
  			}
  
  			if event.Op&Rename == Rename || event.Op&Remove == Remove {
  				w.Remove(event.Name)
  				w.mu.Lock()
  				delete(w.fileExists, event.Name)
  				w.mu.Unlock()
  			}
  
  			if path.isDir && event.Op&Write == Write && !(event.Op&Remove == Remove) {
  				w.sendDirectoryChangeEvents(event.Name)
  			} else {
  				// Send the event on the Events channel
  				w.Events <- event
  			}
  
  			if event.Op&Remove == Remove {
  				// Look for a file that may have overwritten this.
  				// For example, mv f1 f2 will delete f2, then create f2.
  				if path.isDir {
  					fileDir := filepath.Clean(event.Name)
  					w.mu.Lock()
  					_, found := w.watches[fileDir]
  					w.mu.Unlock()
  					if found {
  						// make sure the directory exists before we watch for changes. When we
  						// do a recursive watch and perform rm -fr, the parent directory might
  						// have gone missing, ignore the missing directory and let the
  						// upcoming delete event remove the watch from the parent directory.
  						if _, err := os.Lstat(fileDir); err == nil {
  							w.sendDirectoryChangeEvents(fileDir)
  						}
  					}
  				} else {
  					filePath := filepath.Clean(event.Name)
  					if fileInfo, err := os.Lstat(filePath); err == nil {
  						w.sendFileCreatedEventIfNew(filePath, fileInfo)
  					}
  				}
  			}
  
  			// Move to next event
  			kevents = kevents[1:]
  		}
  	}
  }
  
  // newEvent returns an platform-independent Event based on kqueue Fflags.
  func newEvent(name string, mask uint32) Event {
  	e := Event{Name: name}
  	if mask&unix.NOTE_DELETE == unix.NOTE_DELETE {
  		e.Op |= Remove
  	}
  	if mask&unix.NOTE_WRITE == unix.NOTE_WRITE {
  		e.Op |= Write
  	}
  	if mask&unix.NOTE_RENAME == unix.NOTE_RENAME {
  		e.Op |= Rename
  	}
  	if mask&unix.NOTE_ATTRIB == unix.NOTE_ATTRIB {
  		e.Op |= Chmod
  	}
  	return e
  }
  
  func newCreateEvent(name string) Event {
  	return Event{Name: name, Op: Create}
  }
  
  // watchDirectoryFiles to mimic inotify when adding a watch on a directory
  func (w *Watcher) watchDirectoryFiles(dirPath string) error {
  	// Get all files
  	files, err := ioutil.ReadDir(dirPath)
  	if err != nil {
  		return err
  	}
  
  	for _, fileInfo := range files {
  		filePath := filepath.Join(dirPath, fileInfo.Name())
  		filePath, err = w.internalWatch(filePath, fileInfo)
  		if err != nil {
  			return err
  		}
  
  		w.mu.Lock()
  		w.fileExists[filePath] = true
  		w.mu.Unlock()
  	}
  
  	return nil
  }
  
  // sendDirectoryEvents searches the directory for newly created files
  // and sends them over the event channel. This functionality is to have
  // the BSD version of fsnotify match Linux inotify which provides a
  // create event for files created in a watched directory.
  func (w *Watcher) sendDirectoryChangeEvents(dirPath string) {
  	// Get all files
  	files, err := ioutil.ReadDir(dirPath)
  	if err != nil {
  		w.Errors <- err
  	}
  
  	// Search for new files
  	for _, fileInfo := range files {
  		filePath := filepath.Join(dirPath, fileInfo.Name())
  		err := w.sendFileCreatedEventIfNew(filePath, fileInfo)
  
  		if err != nil {
  			return
  		}
  	}
  }
  
  // sendFileCreatedEvent sends a create event if the file isn't already being tracked.
  func (w *Watcher) sendFileCreatedEventIfNew(filePath string, fileInfo os.FileInfo) (err error) {
  	w.mu.Lock()
  	_, doesExist := w.fileExists[filePath]
  	w.mu.Unlock()
  	if !doesExist {
  		// Send create event
  		w.Events <- newCreateEvent(filePath)
  	}
  
  	// like watchDirectoryFiles (but without doing another ReadDir)
  	filePath, err = w.internalWatch(filePath, fileInfo)
  	if err != nil {
  		return err
  	}
  
  	w.mu.Lock()
  	w.fileExists[filePath] = true
  	w.mu.Unlock()
  
  	return nil
  }
  
  func (w *Watcher) internalWatch(name string, fileInfo os.FileInfo) (string, error) {
  	if fileInfo.IsDir() {
  		// mimic Linux providing delete events for subdirectories
  		// but preserve the flags used if currently watching subdirectory
  		w.mu.Lock()
  		flags := w.dirFlags[name]
  		w.mu.Unlock()
  
  		flags |= unix.NOTE_DELETE | unix.NOTE_RENAME
  		return w.addWatch(name, flags)
  	}
  
  	// watch file to mimic Linux inotify
  	return w.addWatch(name, noteAllEvents)
  }
  
  // kqueue creates a new kernel event queue and returns a descriptor.
  func kqueue() (kq int, err error) {
  	kq, err = unix.Kqueue()
  	if kq == -1 {
  		return kq, err
  	}
  	return kq, nil
  }
  
  // register events with the queue
  func register(kq int, fds []int, flags int, fflags uint32) error {
  	changes := make([]unix.Kevent_t, len(fds))
  
  	for i, fd := range fds {
  		// SetKevent converts int to the platform-specific types:
  		unix.SetKevent(&changes[i], fd, unix.EVFILT_VNODE, flags)
  		changes[i].Fflags = fflags
  	}
  
  	// register the events
  	success, err := unix.Kevent(kq, changes, nil, nil)
  	if success == -1 {
  		return err
  	}
  	return nil
  }
  
  // read retrieves pending events, or waits until an event occurs.
  // A timeout of nil blocks indefinitely, while 0 polls the queue.
  func read(kq int, events []unix.Kevent_t, timeout *unix.Timespec) ([]unix.Kevent_t, error) {
  	n, err := unix.Kevent(kq, nil, events, timeout)
  	if err != nil {
  		return nil, err
  	}
  	return events[0:n], nil
  }
  
  // durationToTimespec prepares a timeout value
  func durationToTimespec(d time.Duration) unix.Timespec {
  	return unix.NsecToTimespec(d.Nanoseconds())
  }
  