<commit_before>//
//  When you open windows outside of tab groups, they are appear on top of either
// 	the current window or the current tab group.  These examples show you different ways
//  to open windows outside of tab groups.
//

var win = Titanium.UI.currentWindow;

win.orientationModes = [
	Titanium.UI.PORTRAIT,
	Titanium.UI.LANDSCAPE_LEFT,
	Titanium.UI.LANDSCAPE_RIGHT
];
win.addEventListener('focus', function()
{
	Ti.API.info('FOCUSED EVENT RECEIVED');
});

//
//  OPEN WINDOW OUTSIDE OF TAB GROUP
//
var b1 = Titanium.UI.createButton({
	title:'Open (Plain)',
	width:200,
	height:40,
	top:10
});

b1.addEventListener('click', function()
{

	var w = Titanium.UI.createWindow({
		backgroundColor:'#336699'
	});

	// create a button to close window
	var b = Titanium.UI.createButton({
		title:'Close',
		height:30,
		width:150
	});
	w.add(b);
	b.addEventListener('click', function()
	{
		w.close();
	});

	w.open();
});

//
//  OPEN (ANIMATE FROM BOTTOM RIGHT)
//
var b2 = Titanium.UI.createButton({
	title:'Open (Nav Bar Covered)',
	width:200,
	height:40,
	top:60
});

b2.addEventListener('click', function()
{
	var options = {
			height:0,
			width:0,
			backgroundColor:'#336699',
			bottom:0,
			right:0
		};
	if (Ti.Platform.name == 'android') {
		options.navBarHidden = true;
	}
	var w = Titanium.UI.createWindow(options);
	var a = Titanium.UI.createAnimation();

	// NOTE: good example of making dynamic platform height / width values
	// iPad vs. iPhone vs Android etc.
	a.height = Titanium.Platform.displayCaps.platformHeight;
	a.width = Titanium.Platform.displayCaps.platformWidth;
	a.duration = 300;

	// create a button to close window
	var b = Titanium.UI.createButton({
		title:'Close',
		height:30,
		width:150
	});
	w.add(b);
	b.addEventListener('click', function()
	{
		a.height = 0;
		a.width = 0;
		w.close(a);
	});

	w.open(a);
});

//
//  TRADITIONAL MODAL (FROM 0.8.x)
//
var b3 = Titanium.UI.createButton({
	title:'Traditional Modal',
	width:200,
	height:40,
	top:110
});

b3.addEventListener('click', function()
{
	var w = Titanium.UI.createWindow({
		backgroundColor:'#336699',
		title:'Modal Window',
		barColor:'black',
		url:'vibrate.js'
	});
	var b = Titanium.UI.createButton({
		title:'Close',
		style:Titanium.UI.iPhone.SystemButtonStyle.PLAIN
	});
	w.setLeftNavButton(b);
	b.addEventListener('click',function()
	{
		w.close();
	});
	w.open({modal:true});
});

//
//  OPEN (WITH ANIMATED WOBBLE)
//
var b4 = Titanium.UI.createButton({
	title:'Open (Animation Fun)',
	width:200,
	height:40,
	top:160
});

b4.addEventListener('click', function()
{
	var t = Titanium.UI.create2DMatrix();
	t = t.scale(0);

	var w = Titanium.UI.createWindow({
		backgroundColor:'#336699',
		borderWidth:8,
		borderColor:'#999',
		height:400,
		width:300,
		borderRadius:10,
		opacity:0.92,
		transform:t
	});

	// create first transform to go beyond normal size
	var t1 = Titanium.UI.create2DMatrix();
	t1 = t1.scale(1.1);
	var a = Titanium.UI.createAnimation();
	a.transform = t1;
	a.duration = 200;

	// when this animation completes, scale to normal size
	a.addEventListener('complete', function()
	{
		Titanium.API.info('here in complete');
		var t2 = Titanium.UI.create2DMatrix();
		t2 = t2.scale(1.0);
		w.animate({transform:t2, duration:200});

	});

	// create a button to close window
	var b = Titanium.UI.createButton({
		title:'Close',
		height:30,
		width:150
	});
	w.add(b);
	b.addEventListener('click', function()
	{
		var t3 = Titanium.UI.create2DMatrix();
		t3 = t3.scale(0);
		w.close({transform:t3,duration:300});
	});

	w.open(a);

});

//
// OPEN (ANIMATE FROM BOTTOM)
//
var b5 = Titanium.UI.createButton({
	title:'Open (Nav Bar Visible)',
	width:200,
	height:40,
	top:210
});

b5.addEventListener('click', function()
{
	var w = Titanium.UI.createWindow({
		height:0,
		backgroundColor:'#000',
		bottom:0
	});

	// create window open animation
	var a = Titanium.UI.createAnimation();
	a.height = 420;
	a.duration = 300;

	// create a button to close window
	var b = Titanium.UI.createButton({
		title:'Close',
		height:30,
		width:150
	});
	w.add(b);
	b.addEventListener('click', function()
	{
		a.height = 0;
		w.close(a);
	});

	w.open(a);
});

//
//  OPEN (FULLSCREEN)
//
var b6 = Titanium.UI.createButton({
	title:'Open (Fullscreen)',
	width:200,
	height:40,
	top:260
});

b6.addEventListener('click', function()
{
	var w = Titanium.UI.createWindow({
		backgroundColor:'#336699'
	});

	// create a button to close window
	var b = Titanium.UI.createButton({
		title:'Close',
		height:30,
		width:150
	});
	w.add(b);
	b.addEventListener('click', function()
	{
		w.close();
	});

	w.open({fullscreen:true});
});

//
//  OPEN (CUSTOM TOOLBAR)
//
var b7 = Titanium.UI.createButton({
	title:'Open (Toolbar)',
	width:200,
	height:40,
	top:310
});

b7.addEventListener('click', function()
{
	var label = Titanium.UI.createButton({
		title:'Custom Toolbar',
		color:'#fff',
		style:Titanium.UI.iPhone.SystemButtonStyle.PLAIN
	});

	var flexSpace = Titanium.UI.createButton({
		systemButton:Titanium.UI.iPhone.SystemButton.FLEXIBLE_SPACE
	});
	var close = Titanium.UI.createButton({
		title:'Close',
		style:Titanium.UI.iPhone.SystemButtonStyle.DONE
	});
	var hello = Titanium.UI.createButton({
		title:'Hello',
		style:Titanium.UI.iPhone.SystemButtonStyle.BORDERED
	});

	var w = Titanium.UI.createWindow({
		backgroundColor:'#336699'
	});
	close.addEventListener('click', function()
	{
		Ti.API.info('IN HERE');
		w.close();
	});

	// create and add toolbar
	var toolbar = Titanium.UI.createToolbar({
		items:[hello,flexSpace,label, flexSpace,close],
		top:0,
		borderTop:false,
		borderBottom:true
	});
	w.add(toolbar);

	var move = Titanium.UI.createButton({
		title:'Move Toolbar',
		height:40,
		width:200
	});
	w.add(move);

	move.addEventListener('click', function()
	{
		toolbar.animate({top:20,duration:500});
	});

	w.open();
});

//
// ODD SHAPED WINDOWS
//
var t = Titanium.UI.create2DMatrix();
t= t.rotate(-90);
var menuWin = Titanium.UI.createWindow({
	backgroundImage:'../images/menubox.png',
	height:178,
	width:204,
	top:32,
	right:40,
	anchorPoint:{x:1,y:0},
	transform:t,
	opacity:0
});

var t2 = Titanium.UI.create2DMatrix();

var navButton = Titanium.UI.createButton({
	title:'Toggle Window'
});
var visible = false;
navButton.addEventListener('click', function()
{
	if (!visible)
	{
		menuWin.open();
		menuWin.animate({transform:t2,opacity:1,duration:800});
		visible=true;
	}
	else
	{
		var t = Titanium.UI.create2DMatrix();
		t= t.rotate(-90);
		menuWin.animate({transform:t,opacity:0,duration:800}, function()
		{
			menuWin.close();
		});
		visible=false;
	}
});

win.add(b1);
win.add(b2);
win.add(b3);
win.add(b6);

if (Titanium.Platform.name == 'iPhone OS')
{
	win.setRightNavButton(navButton);
	win.add(b7);
	win.add(b4);
	win.add(b5);

}
else
{
	navButton.top = 310;
	navButton.width = 200;
	navButton.height = 40;
//	win.add(navButton);
}

<commit_msg>test change<commit_after>//
//  When you open windows outside of tab groups, they are appear on top of either
// 	the current window or the current tab group.  These examples show you different ways
//  to open windows outside of tab groups.
//

var win = Titanium.UI.currentWindow;

win.orientationModes = [
	Titanium.UI.PORTRAIT,
	Titanium.UI.LANDSCAPE_LEFT,
	Titanium.UI.LANDSCAPE_RIGHT
];
win.addEventListener('focus', function()
{
	Ti.API.info('FOCUSED EVENT RECEIVED');
});

//
//  OPEN WINDOW OUTSIDE OF TAB GROUP
//
var b1 = Titanium.UI.createButton({
	title:'Open (Plain)',
	width:200,
	height:40,
	top:10
});

b1.addEventListener('click', function()
{

	var w = Titanium.UI.createWindow({
		backgroundColor:'#336699'
	});

	// create a button to close window
	var b = Titanium.UI.createButton({
		title:'Close',
		height:30,
		width:150
	});
	w.add(b);
	b.addEventListener('click', function()
	{
		w.close();
	});

	w.open();
});

//
//  OPEN (ANIMATE FROM BOTTOM RIGHT)
//
var b2 = Titanium.UI.createButton({
	title:'Open (Nav Bar Covered)',
	width:200,
	height:40,
	top:60
});

b2.addEventListener('click', function()
{
	var options = {
			height:0,
			width:0,
			backgroundColor:'#336699',
			bottom:0,
			right:0
		};
	if (Ti.Platform.name == 'android') {
		options.navBarHidden = true;
	}
	var w = Titanium.UI.createWindow(options);
	var a = Titanium.UI.createAnimation();

	// NOTE: good example of making dynamic platform height / width values
	// iPad vs. iPhone vs Android etc.
	a.height = Titanium.Platform.displayCaps.platformHeight;
	a.width = Titanium.Platform.displayCaps.platformWidth;
	a.duration = 300;

	// create a button to close window
	var b = Titanium.UI.createButton({
		title:'Close',
		height:30,
		width:150
	});
	w.add(b);
	b.addEventListener('click', function()
	{
		a.height = 0;
		a.width = 0;
		w.close(a);
	});

	w.open(a);
});

//
//  TRADITIONAL MODAL (FROM 0.8.x)
//
var b3 = Titanium.UI.createButton({
	title:'Traditional Modal',
	width:200,
	height:40,
	top:110
});

b3.addEventListener('click', function()
{
	var w = Titanium.UI.createWindow({
		backgroundColor:'#336699',
		title:'Modal Window',
		barColor:'black',
		url:'vibrate.js'
	});
	var b = Titanium.UI.createButton({
		title:'Close',
		style:Titanium.UI.iPhone.SystemButtonStyle.PLAIN
	});
	w.setLeftNavButton(b);
	b.addEventListener('click',function()
	{
		w.close();
	});
	w.open({modal:true});
});

//
//  OPEN (WITH ANIMATED WOBBLE)
//
var b4 = Titanium.UI.createButton({
	title:'Open (Animation Fun)',
	width:200,
	height:40,
	top:160
});

b4.addEventListener('click', function()
{
	var t = Titanium.UI.create2DMatrix();
	t = t.scale(0);

	var w = Titanium.UI.createWindow({
		backgroundColor:'#336699',
		borderWidth:8,
		borderColor:'#999',
		height:400,
		width:300,
		borderRadius:10,
		opacity:0.92,
		transform:t
	});

	// create first transform to go beyond normal size
	var t1 = Titanium.UI.create2DMatrix();
	t1 = t1.scale(1.1);
	var a = Titanium.UI.createAnimation();
	a.transform = t1;
	a.duration = 200;

	// when this animation completes, scale to normal size
	a.addEventListener('complete', function()
	{
		Titanium.API.info('here in complete');
		var t2 = Titanium.UI.create2DMatrix();
		t2 = t2.scale(1.0);
		w.animate({transform:t2, duration:200});

	});

	// create a button to close window
	var b = Titanium.UI.createButton({
		title:'Close',
		height:30,
		width:150
	});
	w.add(b);
	b.addEventListener('click', function()
	{
		var t3 = Titanium.UI.create2DMatrix();
		t3 = t3.scale(0);
		w.close({transform:t3,duration:300});
	});

	w.open(a);

});

//
// OPEN (ANIMATE FROM BOTTOM)
//
var b5 = Titanium.UI.createButton({
	title:'Open (Nav Bar Visible)',
	width:200,
	height:40,
	top:210
});

b5.addEventListener('click', function()
{
	var w = Titanium.UI.createWindow({
		height:0,
		backgroundColor:'#000',
		bottom:0
	});

	// create window open animation
	var a = Titanium.UI.createAnimation();
	a.height = 420;
	a.duration = 300;

	// create a button to close window
	var b = Titanium.UI.createButton({
		title:'Close',
		height:30,
		width:150
	});
	w.add(b);
	b.addEventListener('click', function()
	{
		a.height = 0;
		w.close(a);
	});

	w.open(a);
});

//
//  OPEN (FULLSCREEN)
//
var b6 = Titanium.UI.createButton({
	title:'Open (Fullscreen)',
	width:200,
	height:40,
	top:260
});

b6.addEventListener('click', function()
{
	var w = Titanium.UI.createWindow({
		backgroundColor:'#336699'
	});

	// create a button to close window
	var b = Titanium.UI.createButton({
		title:'Close',
		height:30,
		width:150
	});
	w.add(b);
	b.addEventListener('click', function()
	{
		w.close();
	});

	w.open({fullscreen:true});
});

//
//  OPEN (CUSTOM TOOLBAR)
//
var b7 = Titanium.UI.createButton({
	title:'Open (Toolbar)',
	width:200,
	height:40,
	top:310
});

b7.addEventListener('click', function()
{
	var label = Titanium.UI.createButton({
		title:'Custom Toolbar',
		color:'#fff',
		style:Titanium.UI.iPhone.SystemButtonStyle.PLAIN
	});

	var flexSpace = Titanium.UI.createButton({
		systemButton:Titanium.UI.iPhone.SystemButton.FLEXIBLE_SPACE
	});
	var close = Titanium.UI.createButton({
		title:'Close',
		style:Titanium.UI.iPhone.SystemButtonStyle.DONE
	});
	var hello = Titanium.UI.createButton({
		title:'Hello',
		style:Titanium.UI.iPhone.SystemButtonStyle.BORDERED
	});

	var w = Titanium.UI.createWindow({
		backgroundColor:'#336699'
	});
	close.addEventListener('click', function()
	{
		Ti.API.info('IN HERE');
		w.close();
	});

	// create and add toolbar
	var toolbar = Titanium.UI.createToolbar({
		items:[hello,flexSpace,label, flexSpace,close],
		top:0,
		borderTop:false,
		borderBottom:true
	});
	w.add(toolbar);

	var move = Titanium.UI.createButton({
		title:'Move Toolbar',
		height:40,
		width:200
	});
	w.add(move);

	move.addEventListener('click', function()
	{
		toolbar.animate({top:20,duration:500});
	});

	w.open();
});

//
// ODD SHAPED WINDOWS
//
var t = Titanium.UI.create2DMatrix();
t= t.rotate(-90);
var menuWin = Titanium.UI.createWindow({
	backgroundImage:'../images/menubox.png',
	height:178,
	width:204,
	top:32,
	right:40,
	anchorPoint:{x:1,y:0},
	transform:t,
	opacity:0
});

var t2 = Titanium.UI.create2DMatrix();

var navButton = Titanium.UI.createButton({
	title:'Toggle Window'
});
var visible = false;
navButton.addEventListener('click', function()
{
	if (!visible)
	{
		menuWin.open();
		menuWin.animate({transform:t2,opacity:1,duration:800});
		visible=true;
	}
	else
	{
		var t = Titanium.UI.create2DMatrix();
		t= t.rotate(-90);
		menuWin.animate({transform:t,opacity:0,duration:800}, function()
		{
			menuWin.close();
		});
		visible=false;
	}
});

win.add(b1);
win.add(b2);
win.add(b3);
win.add(b6);

if (Titanium.Platform.name == 'iPhone OS')
{
	win.setRightNavButton(navButton);
	win.add(b7);
	win.add(b4);
	win.add(b5);
	var flexSpace = Titanium.UI.createButton({
		style:Titanium.UI.iPhone.SystemButtonStyle.FLEXIBLE_SPACE
	});

	win.setToolbar([flexSpace],{translucent:true});

}
else
{
	navButton.top = 310;
	navButton.width = 200;
	navButton.height = 40;
//	win.add(navButton);
}

<|endoftext|>


<commit_before>import PropTypes from "prop-types";
import React, { useCallback, useState } from "react";
import styled from "styled-components";

import style from "@agir/front/genericComponents/_variables.scss";

import Button from "@agir/front/genericComponents/Button";
import CSRFProtectedForm from "@agir/front/genericComponents/CSRFProtectedForm";
import FeatherIcon, {
  RawFeatherIcon,
} from "@agir/front/genericComponents/FeatherIcon";
import Popin from "@agir/front/genericComponents/Popin";
import BottomSheet from "@agir/front/genericComponents/BottomSheet";
import { ResponsiveLayout } from "@agir/front/genericComponents/grid";

const StyledList = styled.ul`
  width: 100%;
  cursor: pointer;
  display: flex;
  flex-flow: column nowrap;
  align-items: stretch;
  list-style: none;
  color: ${style.primary500};
  padding: 0;

  @media (max-width: ${style.collapse}px) {
    margin: 0;
    padding: 1.5rem;
  }

  a {
    display: flex;
    align-items: center;
    border: none;
    padding: 0;
    margin: 0;
    text-decoration: none;
    background: inherit;
    cursor: pointer;
    text-align: center;
    -webkit-appearance: none;
    -moz-appearance: none;
    font-size: 0.875rem;
    line-height: 20px;
    font-weight: 400;
    color: ${style.black1000};
    margin-bottom: 0.5rem;

    &:last-child {
      margin-bottom: 0;
    }

    &:hover,
    &:focus {
      text-decoration: underline;
      border: none;
      outline: none;
    }

    &[disabled],
    &[disabled]:hover,
    &[disabled]:focus {
      opacity: 0.75;
      text-decoration: none;
      cursor: default;
    }

    @media (max-width: ${style.collapse}px) {
      margin-bottom: 1.5rem;
      text-decoration: none;
    }

    & > *:first-child {
      margin-right: 0.5rem;
      width: 1rem;
      height: 1rem;

      @media (max-width: ${style.collapse}px) {
        margin-right: 1rem;-
        width: 1.5rem;
        height: 1.5rem;
      }

      svg {
        width: inherit;
        height: inherit;
        stroke-width: 2;
      }
    }
  }
`;
const StyledPanel = styled.div`
  width: 100%;
  background-color: ${style.primary100};
  padding: 1.5rem;
  margin: 0;

  @media (max-width: ${style.collapse}px) {
    display: none;
  }

  h6 {
    margin: 0;
    font-size: 1rem;
    line-height: 1;
    color: ${style.primary500};
    margin-bottom: 1rem;
    font-weight: bold;
  }

  && ul {
    list-style: none;
    padding: 0;
    margin: 0;

    li {
      font-size: 0.813rem;
      line-height: 1.3;
      display: flex;
      align-items: baseline;

      a {
        color: ${style.black1000};
        margin-left: 0.5rem;
      }
    }

    li + li {
      margin-top: 0.5rem;
    }

    li {
      align-items: center;
      font-weight: normal;
      font-size: 0.875rem;

      a {
        margin-left: 0.5rem;
      }

      ${RawFeatherIcon} {
        svg {
          stroke-width: 2px;
          width: 1rem;
          height: 1rem;
        }
      }
    }
  }

  ${Button} + ul {
    margin-top: 1rem;
  }

  & ~ ${Button} {
    @media (min-width: ${style.collapse}px) {
      display: none;
    }
  }
`;
const StyledContent = styled.div`
  padding: 0;
  display: flex;
  align-items: flex-start;
  flex-flow: column nowrap;
  margin-bottom: 2rem;

  @media (max-width: ${style.collapse}px) {
    background-color: white;
    width: 100%;
    padding: 0 1rem 1.5rem;
    margin-bottom: 0;
    align-items: center;
    display: ${({ hideOnMobile }) => (hideOnMobile ? "none" : "flex")};
  }

  & > ${Button} {
    margin: 0;
    width: 100%;
    justify-content: center;
  }

  & > ${Button} + ${Button} {
    margin-top: 0.75rem;
  }

  p {
    margin-top: 0.5rem;
    font-weight: 500;
    font-size: 0.813rem;
    line-height: 1.5;
    color: ${style.black500};
    margin-bottom: 0;

    @media (max-width: ${style.collapse}px) {
      font-size: 0.688rem;
      font-weight: 400;
      color: ${style.black1000};
    }
  }
`;

const StyledAdminButton = styled.div`
  width: 100%;
  margin-bottom: 0.75rem;
  text-align: center;

  ${Button} {
    justify-content: center;
    width: 100%;
    cursor: pointer;

    @media (max-width: ${style.collapse}px) {
      width: auto;
    }
  }
`;

const ManagerActions = (props) => {
  const { is2022 = false, routes } = props;

  return (

      <Button
        as="a"
        href={routes.createEvent}
        color="primary"
        icon="plus"
        small
      >
        Créer un événement {is2022 ? "de l'équipe" : "du groupe"}
      </Button>
      <Button as="a" href={routes.settings} icon="settings" small>
        Gestion {is2022 ? "de l'équipe" : "du groupe"}
      </Button>
    </StyledContent>
  );
};

const MobileMemberActions = (props) => {
  const { is2022 = false, routes, isMenuOpen, openMenu, closeMenu } = props;

  return (

      <Button onClick={openMenu} color="default" icon="check" small>
        Vous êtes membre {is2022 ? "de l'équipe" : "du groupe"}
      </Button>
      <BottomSheet isOpen={isMenuOpen} onDismiss={closeMenu} position="bottom">

      </BottomSheet>

  );
};
const DesktopMemberActions = (props) => {
  const { is2022 = false, routes, isMenuOpen, openMenu, closeMenu } = props;

  return (

      <Button onClick={openMenu} color="default" icon="check">
        Vous êtes membre {is2022 ? "de l'équipe" : "du groupe"}
      </Button>
      <Popin isOpen={isMenuOpen} onDismiss={closeMenu} position="bottom">

      </Popin>

  );
};
DesktopMemberActions.propTypes = MobileMemberActions.propTypes = {
  is2022: PropTypes.bool,
  routes: PropTypes.object,
  isMenuOpen: PropTypes.bool,
  openMenu: PropTypes.func,
  closeMenu: PropTypes.func,
};
const MemberActions = (props) => {
  const [isMenuOpen, setIsMenuOpen] = useState(false);
  const openMenu = useCallback(() => setIsMenuOpen(true), []);
  const closeMenu = useCallback(() => setIsMenuOpen(false), []);

  return (

  );
};

const NonMemberActions = (props) => {
  const { is2022 = false, routes } = props;

  return (

  );
};

const GroupUserActions = (props) => {
  let Actions = NonMemberActions;

  if (props.isManager) {
    Actions = ManagerActions;
  } else if (props.isMember) {
    Actions = MemberActions;
  }

  return (
    <>
      {props.routes && props.routes.admin && (

      )}
      <Actions {...props} />
    </>
  );
};

ManagerActions.propTypes = MemberActions.propTypes = NonMemberActions.propTypes = GroupUserActions.propTypes = {
  isMember: PropTypes.bool,
  isManager: PropTypes.bool,
  is2022: PropTypes.bool,
  routes: PropTypes.object,
};
export default GroupUserActions;
<commit_msg>fix: non member group page user action typo<commit_after>import PropTypes from "prop-types";
import React, { useCallback, useState } from "react";
import styled from "styled-components";

import style from "@agir/front/genericComponents/_variables.scss";

import Button from "@agir/front/genericComponents/Button";
import CSRFProtectedForm from "@agir/front/genericComponents/CSRFProtectedForm";
import FeatherIcon, {
  RawFeatherIcon,
} from "@agir/front/genericComponents/FeatherIcon";
import Popin from "@agir/front/genericComponents/Popin";
import BottomSheet from "@agir/front/genericComponents/BottomSheet";
import { ResponsiveLayout } from "@agir/front/genericComponents/grid";

const StyledList = styled.ul`
  width: 100%;
  cursor: pointer;
  display: flex;
  flex-flow: column nowrap;
  align-items: stretch;
  list-style: none;
  color: ${style.primary500};
  padding: 0;

  @media (max-width: ${style.collapse}px) {
    margin: 0;
    padding: 1.5rem;
  }

  a {
    display: flex;
    align-items: center;
    border: none;
    padding: 0;
    margin: 0;
    text-decoration: none;
    background: inherit;
    cursor: pointer;
    text-align: center;
    -webkit-appearance: none;
    -moz-appearance: none;
    font-size: 0.875rem;
    line-height: 20px;
    font-weight: 400;
    color: ${style.black1000};
    margin-bottom: 0.5rem;

    &:last-child {
      margin-bottom: 0;
    }

    &:hover,
    &:focus {
      text-decoration: underline;
      border: none;
      outline: none;
    }

    &[disabled],
    &[disabled]:hover,
    &[disabled]:focus {
      opacity: 0.75;
      text-decoration: none;
      cursor: default;
    }

    @media (max-width: ${style.collapse}px) {
      margin-bottom: 1.5rem;
      text-decoration: none;
    }

    & > *:first-child {
      margin-right: 0.5rem;
      width: 1rem;
      height: 1rem;

      @media (max-width: ${style.collapse}px) {
        margin-right: 1rem;-
        width: 1.5rem;
        height: 1.5rem;
      }

      svg {
        width: inherit;
        height: inherit;
        stroke-width: 2;
      }
    }
  }
`;
const StyledPanel = styled.div`
  width: 100%;
  background-color: ${style.primary100};
  padding: 1.5rem;
  margin: 0;

  @media (max-width: ${style.collapse}px) {
    display: none;
  }

  h6 {
    margin: 0;
    font-size: 1rem;
    line-height: 1;
    color: ${style.primary500};
    margin-bottom: 1rem;
    font-weight: bold;
  }

  && ul {
    list-style: none;
    padding: 0;
    margin: 0;

    li {
      font-size: 0.813rem;
      line-height: 1.3;
      display: flex;
      align-items: baseline;

      a {
        color: ${style.black1000};
        margin-left: 0.5rem;
      }
    }

    li + li {
      margin-top: 0.5rem;
    }

    li {
      align-items: center;
      font-weight: normal;
      font-size: 0.875rem;

      a {
        margin-left: 0.5rem;
      }

      ${RawFeatherIcon} {
        svg {
          stroke-width: 2px;
          width: 1rem;
          height: 1rem;
        }
      }
    }
  }

  ${Button} + ul {
    margin-top: 1rem;
  }

  & ~ ${Button} {
    @media (min-width: ${style.collapse}px) {
      display: none;
    }
  }
`;
const StyledContent = styled.div`
  padding: 0;
  display: flex;
  align-items: flex-start;
  flex-flow: column nowrap;
  margin-bottom: 2rem;

  @media (max-width: ${style.collapse}px) {
    background-color: white;
    width: 100%;
    padding: 0 1rem 1.5rem;
    margin-bottom: 0;
    align-items: center;
    display: ${({ hideOnMobile }) => (hideOnMobile ? "none" : "flex")};
  }

  & > ${Button} {
    margin: 0;
    width: 100%;
    justify-content: center;
  }

  & > ${Button} + ${Button} {
    margin-top: 0.75rem;
  }

  p {
    margin-top: 0.5rem;
    font-weight: 500;
    font-size: 0.813rem;
    line-height: 1.5;
    color: ${style.black500};
    margin-bottom: 0;

    @media (max-width: ${style.collapse}px) {
      font-size: 0.688rem;
      font-weight: 400;
      color: ${style.black1000};
    }
  }
`;

const StyledAdminButton = styled.div`
  width: 100%;
  margin-bottom: 0.75rem;
  text-align: center;

  ${Button} {
    justify-content: center;
    width: 100%;
    cursor: pointer;

    @media (max-width: ${style.collapse}px) {
      width: auto;
    }
  }
`;

const ManagerActions = (props) => {
  const { is2022 = false, routes } = props;

  return (

      <Button
        as="a"
        href={routes.createEvent}
        color="primary"
        icon="plus"
        small
      >
        Créer un événement {is2022 ? "de l'équipe" : "du groupe"}
      </Button>
      <Button as="a" href={routes.settings} icon="settings" small>
        Gestion {is2022 ? "de l'équipe" : "du groupe"}
      </Button>
    </StyledContent>
  );
};

const MobileMemberActions = (props) => {
  const { is2022 = false, routes, isMenuOpen, openMenu, closeMenu } = props;

  return (

      <Button onClick={openMenu} color="default" icon="check" small>
        Vous êtes membre {is2022 ? "de l'équipe" : "du groupe"}
      </Button>
      <BottomSheet isOpen={isMenuOpen} onDismiss={closeMenu} position="bottom">

      </BottomSheet>

  );
};
const DesktopMemberActions = (props) => {
  const { is2022 = false, routes, isMenuOpen, openMenu, closeMenu } = props;

  return (

      <Button onClick={openMenu} color="default" icon="check">
        Vous êtes membre {is2022 ? "de l'équipe" : "du groupe"}
      </Button>
      <Popin isOpen={isMenuOpen} onDismiss={closeMenu} position="bottom">

      </Popin>

  );
};
DesktopMemberActions.propTypes = MobileMemberActions.propTypes = {
  is2022: PropTypes.bool,
  routes: PropTypes.object,
  isMenuOpen: PropTypes.bool,
  openMenu: PropTypes.func,
  closeMenu: PropTypes.func,
};
const MemberActions = (props) => {
  const [isMenuOpen, setIsMenuOpen] = useState(false);
  const openMenu = useCallback(() => setIsMenuOpen(true), []);
  const closeMenu = useCallback(() => setIsMenuOpen(false), []);

  return (

  );
};

const NonMemberActions = (props) => {
  const { is2022 = false, routes } = props;

  return (

  );
};

const GroupUserActions = (props) => {
  let Actions = NonMemberActions;

  if (props.isManager) {
    Actions = ManagerActions;
  } else if (props.isMember) {
    Actions = MemberActions;
  }

  return (
    <>
      {props.routes && props.routes.admin && (

      )}
      <Actions {...props} />
    </>
  );
};

ManagerActions.propTypes = MemberActions.propTypes = NonMemberActions.propTypes = GroupUserActions.propTypes = {
  isMember: PropTypes.bool,
  isManager: PropTypes.bool,
  is2022: PropTypes.bool,
  routes: PropTypes.object,
};
export default GroupUserActions;
<|endoftext|>


<commit_before>/**
 * Created by yangm11 on 5/24/2017.
 */
'use strict';

// arr is an array of natural numbers
// arr.length > 2
// all elements of arr < target
// sum of elements of arr > target
// judge whether a sub group of arr sums to target

function judge(arr, target) {
  var result = [];

  if (target === 0) {
    return ['==>'];
  }

  if (target < 0) {
    return false;
  }

  // Due to sum of elements of arr > target, there must be at least one element left.
  // The very deepest 'state' that the recursion can reach should be [elem1, elem2],
  // for the goal to be accomplished, either elem1 or elem2 should be equal to the updated target.
  // Otherwise, it fails.
  // However, in most of time, it never reach that deep, it will stop at updated target <= 0.

  if (arr.length === 2) {
    if (arr[0] === target) {
      return [arr[0]];
    }
    if (arr[1] === target) {
      return [arr[1]];
    }
    return false;
  }

  for (var i = 0; i < arr.length; i++) {
    let newArr = arr.slice();
    newArr.splice(i);
    var t = judge(newArr, target - arr[i]);
    if (t) {
      result = t.concat(arr[i]);
      return result;
    }
  }

  return false;
}

// var test = judge([3, 6, 8, 9, 17, 21, 45, 34, 7, 4, 12 ], 37);
// console.log(test);

// for (var i = 1; i < 100; i++) {
// 	console.log('To reach ' + i, judge([3, 6, 8, 9, 17, 21, 45, 34, 7, 4, 12 ], i));
// }

var testArr = [];
for (var j = 0; j < 100; j++) {
  var t = Math.random() * 1000;
  testArr.push(Math.floor(t));
}

console.log(testArr);

for (var i = 1001; i < 1105; i++) {
  console.log('To reach ' + i, judge(testArr, i));
}<commit_msg>number partition code cleaned<commit_after>/**
 * Created by yangm11 on 5/24/2017.
 * Modified on 1/9/2019.
 * A version that tolerate a specified error can be found with the link below
 * https://github.com/mingzhangyang/go-learning/blob/master/snippets/partition.go
 */
'use strict';

// arr is an array of natural numbers
// arr.length > 2
// all elements of arr < target
// sum of elements of arr > target
// judge whether a sub group of arr sums to target

function judge(arr, target) {
  if (target === 0) { // this is very important!!!!!!
    return [];
  }

  if (target < 0) { //  this is very important!!!!!!!!!!
    return false;
  }

  if (arr.length === 1) {
    if (arr[0] !== target) {
      return false;
    }
    return arr;
  }

  // Due to sum of elements of arr > target, there must be at least one element left.
  // The very deepest 'state' that the recursion can reach should be [elem1, elem2],
  // for the goal to be accomplished, either elem1 or elem2 should be equal to the updated target.
  // Otherwise, it fails.
  // However, in most of time, it never reach that deep, it will stop at updated target <= 0.

  // if (arr.length === 2) {
  //   if (arr[0] === target) {
  //     return [arr[0]];
  //   }
  //   if (arr[1] === target) {
  //     return [arr[1]];
  //   }
  //   return false;
  // }

  for (var i = 0; i < arr.length; i++) {
    let newArr = arr.slice();
    newArr.splice(i);
    var t = judge(newArr, target - arr[i]);
    if (t) {
      return t.concat(arr[i]);
    }
  }

  return false;
}

console.log(judge([1], 2));
console.log(judge([2], 2));
console.log(judge([2, 3], 2));
console.log(judge([2, 3], 4));
console.log(judge([2, 3, 7], 4));
console.log(judge([2, 3, 7], 5));

var test = judge([3, 6, 8, 9, 17, 21, 45, 34, 7, 4, 12 ], 37);
console.log(test);

// for (var i = 1; i < 100; i++) {
// 	console.log('To reach ' + i, judge([3, 6, 8, 9, 17, 21, 45, 34, 7, 4, 12 ], i));
// }

// var testArr = [];
// for (var j = 0; j < 100; j++) {
//   var t = Math.random() * 1000;
//   testArr.push(Math.floor(t));
// }
//
// console.log(testArr);
//
// for (var i = 1001; i < 1105; i++) {
//   console.log('To reach ' + i, judge(testArr, i));
// }<|endoftext|>


<commit_before>// Place all the behaviors and hooks related to the matching controller here.
// All this logic will automatically be available in application.js.
$(function(){
  $(".datatable").dataTable({
    "order": [[8, "desc"]]
  })
})
<commit_msg>changing date sorting to asc<commit_after>// Place all the behaviors and hooks related to the matching controller here.
// All this logic will automatically be available in application.js.
$(function(){
  $(".datatable").dataTable({
    "order": [[8, "asc"]]
  })
})
<|endoftext|>


<commit_before>angular.module('documentationEditorApp', [])
  .config(['$locationProvider', function($locationProvider) {
    $locationProvider.html5Mode({ enabled: true, requireBase: false, rewriteLinks: false });
  }])
  .controller('EditorController', ['$scope', '$http', '$window', '$location', function($scope, $http, $window, $location) {
    $scope.sections = [];
    $scope.undoRedo = [];
    $scope.id = 0;
    $scope.source = '';

    $scope.nextID = 0;
    function getNextID() {
      return $scope.nextID++;
    }

    function parse(source) {
      var lines = source.replace(/\n{3,}/g, "\n\n").split("\n");
      var currentBlock = null, blockContent = '';
      var sections = [];
      for (var i = 0; i < lines.length; ++i) {
        var line = lines[i];
        if (line.indexOf('[block:') === 0) {
          currentBlock = line.substring(7, line.length - 1);
        } else if (line.indexOf('[/block]') === 0) {
          sections.push({
            id: getNextID(),
            type: currentBlock,
            content: JSON.parse(blockContent)
          });
          currentBlock = null;
          blockContent = '';
        } else if (currentBlock != null) {
          blockContent = blockContent + line + '\n';
        } else {
          if (sections.length > 0 && sections[sections.length - 1].type === 'text') {
            sections[sections.length - 1].content = sections[sections.length - 1].content + "\n" + line;
          } else if (line) {
            sections.push({
              id: getNextID(),
              type: 'text',
              content: line
            });
          }
        }
      }
      return sections;
    }

    function serialize(sections) {
      var data = [];
      $.each(sections, function(i, section) {
        if (section.type === 'text') {
          data.push(section.content + "\n");
        } else {
          data.push('[block:' + section.type + ']');
          data.push(JSON.stringify(section.content));
          data.push("[/block]\n");
        }
      });
      return data.join("\n");
    }

    $scope.init = function(id, path) {
      $scope.id = id;
      $scope.path = path;

      $http.get($scope.path + '/source/' + id).then(function(content) {
        $scope.source = content.data;
        $scope.sections = parse($scope.source);
      });
    };

    $scope.rawView =  false;
    $scope.toggleView = function($event) {
      $event.preventDefault();
      $scope.undoRedo = [];
      if ($scope.rawView) {
        $scope.sections = parse(this.source);
      } else {
        $scope.source = serialize($scope.sections);
      }
      $scope.rawView = !$scope.rawView;
    };

    $scope.undo = function($event) {
      $event.preventDefault();
      if ($scope.undoRedo.length === 0) {
        return;
      }
      var o = $scope.undoRedo.pop();
      if (o.type === 'addSection') {
        $scope.sections = $.grep($scope.sections, function(e) { return e.id !== o.data.obj.id });
      } else if (o.type === 'deleteSection') {
        $scope.sections = o.data.sections;
      } else if (o.type === 'deleteLanguage' || o.type === 'addLanguage') {
        var index = getIndex(o.data.id);
        var obj = {
          id: $scope.sections[index].id,
          type: 'code',
          content: {
            codes: o.data.codes
          }
        };
        $scope.sections = [].concat($scope.sections.slice(0, index), [obj], $scope.sections.slice(index + 1));
      } else if (o.type === 'deleteColumn' || o.type === 'addColumn' || o.type === 'addRow' || o.type === 'deleteRow') {
        var index = getIndex(o.data.id);
        $scope.sections[index] = {
          id: $scope.sections[index].id,
          type: 'parameters',
          content: o.data.content
        };
      }
    }

    function getIndex(id) {
      for (var i = 0; i < $scope.sections.length; ++i) {
        if ($scope.sections[i].id === id) {
          return i;
        }
      }
      return -1;
    }

    function add(id, obj) {
      $scope.undoRedo.push({
        type: 'addSection',
        data: {
          id: id,
          obj: obj
        }
      });
      var index = getIndex(id);
      $scope.sections = [].concat($scope.sections.slice(0, index + 1), [obj], $scope.sections.slice(index + 1));
    }

    $scope.addText = function($event, id) {
      $event.preventDefault();
      add(id, { id: getNextID(), type: 'text', content: 'FIXME' });
    };

    $scope.addCallout = function($event, type, id) {
      $event.preventDefault();
      add(id, {
        id: getNextID(),
        type: 'callout',
        content: {
          type: type,
          body: 'FIXME'
        }
      });
    };

    $scope.addCode = function($event, id) {
      $event.preventDefault();
      add(id, {
        id: getNextID(),
        type: 'code',
        content: {
          codes: [
            {
              language: 'fixme',
              code: '// FIXME'
            }
          ]
        }
      });
    };

    $scope.getIntegerIterator = function(v) {
      var a = [];
      for (var i = 0; i < v; ++i) {
        a.push(i);
      }
      return a;
    };

    $scope.deleteSection = function($event, id) {
      $event.preventDefault();
      $scope.undoRedo.push({
        type: 'deleteSection',
        data: {
          sections: $scope.sections
        }
      });
      $scope.sections = $.grep($scope.sections, function(e) { return e.id !== id });
    };

    $scope.deleteLanguage = function($event, id, languageIndex) {
      $event.preventDefault();
      var index = getIndex(id);
      $scope.undoRedo.push({
        type: 'deleteLanguage',
        data: {
          id: id,
          codes: $scope.sections[index].content.codes
        }
      });
      $scope.sections[index].content.codes = $.grep($scope.sections[index].content.codes, function(e, i) { return i !== languageIndex; });
    };

    $scope.addLanguage = function($event, id) {
      $event.preventDefault();
      var index = getIndex(id);
      $scope.undoRedo.push({
        type: 'addLanguage',
        data: {
          id: id,
          codes: $scope.sections[index].content.codes
        }
      });
      $scope.sections[index].content.codes = [].concat($scope.sections[index].content.codes, [{ language: 'fixme', code: '// FIXME' }]);
    };

    $scope.addImage = function($event, id) {
      $event.preventDefault();
      var url = prompt("Image URL (absolute or from after /assets/)", "algolia256x80.png");
      if (url) {
        add(id, {
          type: 'image',
          content: {
            images: [
              {
                image: [url]
              }
            ]
          }
        });
      }
    };

    $scope.addColumn = function($event, id) {
      $event.preventDefault();
      var index = getIndex(id);
      var section = $scope.sections[index];

      $scope.undoRedo.push({
        type: 'addColumn',
        data: {
          id: id,
          content: {
            data: section.content.data,
            cols: section.content.cols,
            rows: section.content.rows
          }
        }
      });

      var col = section.content.cols;
      section.content.data['h-' + col] = section.content.data['h-' + col] || '';
      section.content.cols = section.content.cols + 1;
      for (var i = 0; i < section.content.rows; ++i) {
        section.content.data[i + '-' + col] = section.content.data[i + '-' + col] || '';
      }
    };

    $scope.deleteColumn = function($event, id) {
      $event.preventDefault();
      var index = getIndex(id);
      var section = $scope.sections[index];

      $scope.undoRedo.push({
        type: 'deleteColumn',
        data: {
          id: id,
          content: {
            data: section.content.data,
            cols: section.content.cols,
            rows: section.content.rows
          }
        }
      });

      section.content.cols = section.content.cols - 1;
    };

    $scope.addRow = function($event, id) {
      $event.preventDefault();
      var index = getIndex(id);
      var section = $scope.sections[index];

      $scope.undoRedo.push({
        type: 'addRow',
        data: {
          id: id,
          content: {
            data: section.content.data,
            cols: section.content.cols,
            rows: section.content.rows
          }
        }
      });

      var rows = section.content.rows;
      section.content.rows = section.content.rows + 1;
      for (var i = 0; i < section.content.cols; ++i) {
        section.content.data[rows + '-' + i] = section.content.data[rows + '-' + i] || '';
      }
    };

    $scope.deleteRow = function($event, id) {
      $event.preventDefault();
      var index = getIndex(id);
      var section = $scope.sections[index];

      $scope.undoRedo.push({
        type: 'deleteRow',
        data: {
          id: id,
          content: {
            data: section.content.data,
            cols: section.content.cols,
            rows: section.content.rows
          }
        }
      });

      section.content.rows = section.content.rows - 1;
    };

    $scope.addIf = function($event, id) {
      $event.preventDefault();
      add(id, {
        id: getNextID(),
        type: 'if',
        content: {
          condition: 'FIXME'
        }
      });
    };

    $scope.addEndIf = function($event, id) {
      $event.preventDefault();
      add(id, {
        id: getNextID(),
        type: 'endif',
        content: {}
      });
    };

    $scope.addTable = function($event, id) {
      $event.preventDefault();
      add(id, {
        id: getNextID(),
        type: 'parameters',
        content: {
          cols: 2,
          rows: 2,
          data: {
            'h-0': 'FIXME 1',
            'h-1': 'FIXME 2',
            '0-0': '',
            '0-1': '',
            '1-0': '',
            '1-1': ''
          }
        }
      });
    };

    function save(preview) {
      return $http.post($scope.path + '/source/' + $scope.id, { data: serialize($scope.sections), preview: preview });
    }

    $scope.preview = function($event) {
      $event.preventDefault();
      save(true).then(function(content) {
        $window.open($scope.path + '/preview/' + content.data.id);
        $location.path($scope.path + '/edit/' + content.data.id).replace();
      });
    };

    $scope.publish = function($event) {
      $event.preventDefault();

      if (confirm('Are you sure you want to publish this page?')) {
        save(false).then(function(content) {
          $window.location.href = $scope.path + '/' + content.data.slug;
        });
      }
    }

  }]).directive('contenteditable', ['$document', function($document) {
    return {
      require: 'ngModel',
      link: function(scope, element, attrs, ngModel) {
        function read() {
          var text = element.text().replace(/<div>/g, '').replace(/<\/div>/g, "\n").replace(/<br>/g, "\n").replace(/\n{3,}/g, "\n\n");
          ngModel.$setViewValue(text);
        }

        ngModel.$render = function() {
          element.text(ngModel.$viewValue || "");
        };

        element.bind("blur keyup change", function() {
          scope.$apply(read);
        });

        // force every copy/paste to be plain/text
        element.bind('paste', function(e) {
          e.preventDefault();
          var text = (e.originalEvent || e).clipboardData.getData('text/plain') || '';
          $document[0].execCommand("insertHTML", false, text);
        });
      }
    };
  }])
;
<commit_msg>Cleanup that newlines mess<commit_after>angular.module('documentationEditorApp', [])
  .config(['$locationProvider', function($locationProvider) {
    $locationProvider.html5Mode({ enabled: true, requireBase: false, rewriteLinks: false });
  }])
  .controller('EditorController', ['$scope', '$http', '$window', '$location', function($scope, $http, $window, $location) {
    $scope.sections = [];
    $scope.undoRedo = [];
    $scope.id = 0;
    $scope.source = '';

    $scope.nextID = 0;
    function getNextID() {
      return $scope.nextID++;
    }

    function parse(source) {
      var lines = source.split("\n");
      var currentBlock = null, blockContent = '';
      var sections = [];
      for (var i = 0; i < lines.length; ++i) {
        var line = lines[i];
        if (line.indexOf('[block:') === 0) {
          currentBlock = line.substring(7, line.length - 1);
        } else if (line.indexOf('[/block]') === 0) {
          sections.push({
            id: getNextID(),
            type: currentBlock,
            content: JSON.parse(blockContent)
          });
          currentBlock = null;
          blockContent = '';
        } else if (currentBlock != null) {
          blockContent = blockContent + line + '\n';
        } else {
          if (sections.length > 0 && sections[sections.length - 1].type === 'text') {
            sections[sections.length - 1].content = (sections[sections.length - 1].content + "\n" + line).replace(/\n{2,}$/, "\n\n");
          } else if (line) {
            sections.push({
              id: getNextID(),
              type: 'text',
              content: line
            });
          }
        }
      }
      return sections;
    }

    function serialize(sections) {
      var data = [];
      $.each(sections, function(i, section) {
        if (section.type === 'text') {
          data.push(section.content + "\n");
        } else {
          data.push('[block:' + section.type + ']');
          data.push(JSON.stringify(section.content));
          data.push("[/block]\n");
        }
      });
      return data.join("\n");
    }

    $scope.init = function(id, path) {
      $scope.id = id;
      $scope.path = path;

      $http.get($scope.path + '/source/' + id).then(function(content) {
        $scope.source = content.data;
        $scope.sections = parse($scope.source);
      });
    };

    $scope.rawView =  false;
    $scope.toggleView = function($event) {
      $event.preventDefault();
      $scope.undoRedo = [];
      if ($scope.rawView) {
        $scope.sections = parse(this.source);
      } else {
        $scope.source = serialize($scope.sections);
      }
      $scope.rawView = !$scope.rawView;
    };

    $scope.undo = function($event) {
      $event.preventDefault();
      if ($scope.undoRedo.length === 0) {
        return;
      }
      var o = $scope.undoRedo.pop();
      if (o.type === 'addSection') {
        $scope.sections = $.grep($scope.sections, function(e) { return e.id !== o.data.obj.id });
      } else if (o.type === 'deleteSection') {
        $scope.sections = o.data.sections;
      } else if (o.type === 'deleteLanguage' || o.type === 'addLanguage') {
        var index = getIndex(o.data.id);
        var obj = {
          id: $scope.sections[index].id,
          type: 'code',
          content: {
            codes: o.data.codes
          }
        };
        $scope.sections = [].concat($scope.sections.slice(0, index), [obj], $scope.sections.slice(index + 1));
      } else if (o.type === 'deleteColumn' || o.type === 'addColumn' || o.type === 'addRow' || o.type === 'deleteRow') {
        var index = getIndex(o.data.id);
        $scope.sections[index] = {
          id: $scope.sections[index].id,
          type: 'parameters',
          content: o.data.content
        };
      }
    }

    function getIndex(id) {
      for (var i = 0; i < $scope.sections.length; ++i) {
        if ($scope.sections[i].id === id) {
          return i;
        }
      }
      return -1;
    }

    function add(id, obj) {
      $scope.undoRedo.push({
        type: 'addSection',
        data: {
          id: id,
          obj: obj
        }
      });
      var index = getIndex(id);
      $scope.sections = [].concat($scope.sections.slice(0, index + 1), [obj], $scope.sections.slice(index + 1));
    }

    $scope.addText = function($event, id) {
      $event.preventDefault();
      add(id, { id: getNextID(), type: 'text', content: 'FIXME' });
    };

    $scope.addCallout = function($event, type, id) {
      $event.preventDefault();
      add(id, {
        id: getNextID(),
        type: 'callout',
        content: {
          type: type,
          body: 'FIXME'
        }
      });
    };

    $scope.addCode = function($event, id) {
      $event.preventDefault();
      add(id, {
        id: getNextID(),
        type: 'code',
        content: {
          codes: [
            {
              language: 'fixme',
              code: '// FIXME'
            }
          ]
        }
      });
    };

    $scope.getIntegerIterator = function(v) {
      var a = [];
      for (var i = 0; i < v; ++i) {
        a.push(i);
      }
      return a;
    };

    $scope.deleteSection = function($event, id) {
      $event.preventDefault();
      $scope.undoRedo.push({
        type: 'deleteSection',
        data: {
          sections: $scope.sections
        }
      });
      $scope.sections = $.grep($scope.sections, function(e) { return e.id !== id });
    };

    $scope.deleteLanguage = function($event, id, languageIndex) {
      $event.preventDefault();
      var index = getIndex(id);
      $scope.undoRedo.push({
        type: 'deleteLanguage',
        data: {
          id: id,
          codes: $scope.sections[index].content.codes
        }
      });
      $scope.sections[index].content.codes = $.grep($scope.sections[index].content.codes, function(e, i) { return i !== languageIndex; });
    };

    $scope.addLanguage = function($event, id) {
      $event.preventDefault();
      var index = getIndex(id);
      $scope.undoRedo.push({
        type: 'addLanguage',
        data: {
          id: id,
          codes: $scope.sections[index].content.codes
        }
      });
      $scope.sections[index].content.codes = [].concat($scope.sections[index].content.codes, [{ language: 'fixme', code: '// FIXME' }]);
    };

    $scope.addImage = function($event, id) {
      $event.preventDefault();
      var url = prompt("Image URL (absolute or from after /assets/)", "algolia256x80.png");
      if (url) {
        add(id, {
          type: 'image',
          content: {
            images: [
              {
                image: [url]
              }
            ]
          }
        });
      }
    };

    $scope.addColumn = function($event, id) {
      $event.preventDefault();
      var index = getIndex(id);
      var section = $scope.sections[index];

      $scope.undoRedo.push({
        type: 'addColumn',
        data: {
          id: id,
          content: {
            data: section.content.data,
            cols: section.content.cols,
            rows: section.content.rows
          }
        }
      });

      var col = section.content.cols;
      section.content.data['h-' + col] = section.content.data['h-' + col] || '';
      section.content.cols = section.content.cols + 1;
      for (var i = 0; i < section.content.rows; ++i) {
        section.content.data[i + '-' + col] = section.content.data[i + '-' + col] || '';
      }
    };

    $scope.deleteColumn = function($event, id) {
      $event.preventDefault();
      var index = getIndex(id);
      var section = $scope.sections[index];

      $scope.undoRedo.push({
        type: 'deleteColumn',
        data: {
          id: id,
          content: {
            data: section.content.data,
            cols: section.content.cols,
            rows: section.content.rows
          }
        }
      });

      section.content.cols = section.content.cols - 1;
    };

    $scope.addRow = function($event, id) {
      $event.preventDefault();
      var index = getIndex(id);
      var section = $scope.sections[index];

      $scope.undoRedo.push({
        type: 'addRow',
        data: {
          id: id,
          content: {
            data: section.content.data,
            cols: section.content.cols,
            rows: section.content.rows
          }
        }
      });

      var rows = section.content.rows;
      section.content.rows = section.content.rows + 1;
      for (var i = 0; i < section.content.cols; ++i) {
        section.content.data[rows + '-' + i] = section.content.data[rows + '-' + i] || '';
      }
    };

    $scope.deleteRow = function($event, id) {
      $event.preventDefault();
      var index = getIndex(id);
      var section = $scope.sections[index];

      $scope.undoRedo.push({
        type: 'deleteRow',
        data: {
          id: id,
          content: {
            data: section.content.data,
            cols: section.content.cols,
            rows: section.content.rows
          }
        }
      });

      section.content.rows = section.content.rows - 1;
    };

    $scope.addIf = function($event, id) {
      $event.preventDefault();
      add(id, {
        id: getNextID(),
        type: 'if',
        content: {
          condition: 'FIXME'
        }
      });
    };

    $scope.addEndIf = function($event, id) {
      $event.preventDefault();
      add(id, {
        id: getNextID(),
        type: 'endif',
        content: {}
      });
    };

    $scope.addTable = function($event, id) {
      $event.preventDefault();
      add(id, {
        id: getNextID(),
        type: 'parameters',
        content: {
          cols: 2,
          rows: 2,
          data: {
            'h-0': 'FIXME 1',
            'h-1': 'FIXME 2',
            '0-0': '',
            '0-1': '',
            '1-0': '',
            '1-1': ''
          }
        }
      });
    };

    function save(preview) {
      return $http.post($scope.path + '/source/' + $scope.id, { data: serialize($scope.sections), preview: preview });
    }

    $scope.preview = function($event) {
      $event.preventDefault();
      save(true).then(function(content) {
        $window.open($scope.path + '/preview/' + content.data.id);
        $location.path($scope.path + '/edit/' + content.data.id).replace();
      });
    };

    $scope.publish = function($event) {
      $event.preventDefault();

      if (confirm('Are you sure you want to publish this page?')) {
        save(false).then(function(content) {
          $window.location.href = $scope.path + '/' + content.data.slug;
        });
      }
    }

  }]).directive('contenteditable', ['$document', function($document) {
    return {
      require: 'ngModel',
      link: function(scope, element, attrs, ngModel) {
        function read() {
          var text = element.html().replace(/<div>/g, '').replace(/<\/div>/g, "\n").replace(/<br>/g, "\n").replace(/\n{2,}$/, '');
          ngModel.$setViewValue(text);
        }

        ngModel.$render = function() {
          element.text(ngModel.$viewValue || "");
        };

        element.bind("blur keyup change", function() {
          scope.$apply(read);
        });

        // force every copy/paste to be plain/text
        element.bind('paste', function(e) {
          e.preventDefault();
          var text = (e.originalEvent || e).clipboardData.getData('text/plain') || '';
          $document[0].execCommand("insertHTML", false, text);
        });
      }
    };
  }])
;
<|endoftext|>


<commit_before>// ELMO.Views.QuestionForm
//
// View model for Question form
(function(ns, klass) {

  // constructor
  ns.QuestionForm = klass = function(params) { var self = this;
    self.params = params;

    // hookup type change event and trigger immediately
    var type_box = $('div.question_fields .form_field#qtype_name .control select');
    type_box.on('change', function(e){ self.question_type_changed(); });

    // run the type box changed event immediately
    // this might be the only time it runs since the form might be in show mode
    self.question_type_changed({initial: true});

    // hookup add option set link
    $('div.question_fields a.create_option_set').on('click', function(){ self.show_option_set_form(); return false; });

    // hookup form submit for modal
    $('#create-option-set .btn-primary').on('click', function() {$('form.option_set_form').submit();});

    // register a callback for when option set form submission is done
    $(document).on('option_set_form_submit_success', 'form.option_set_form', function(e, option_set){
      self.option_set_created(option_set);
    });
  };

  // gets the current value of the field with the given name
  // still works if field is read_only
  klass.prototype.field_value = function(field_name) { var self = this;
    var field_div = $('.question_fields .form_field[data-field-name=' + field_name + '] .control');

    // if read only
    if (field_div.is('.read_only')) {
      // first get the wrapper
      var wrapper = field_div.find('.ro-val');

      // now try to get the wrapper's data-val value, or just the wrapper's contents failing that
      return wrapper.data('val') || wrapper.text();

    // otherwise (not read only) just get the field value
    } else
      return field_div.find('input, select, textarea').val();
  }

  klass.prototype.question_type_changed = function(options) { var self = this;
    var selected_type = self.field_value('qtype_name');

    // Show/hide option set field and hint
    options = options || {};
    options.multilevel = selected_type == 'select_one';
    self.show_option_set_select(selected_type == 'select_one' || selected_type == 'select_multiple', options);

    // show/hide max/min
    var show_max_min = (selected_type == "decimal" || selected_type == "integer");
    $(".question_fields .minmax")[show_max_min ? 'show' : 'hide']();

    // reset boxes if hiding
    if (!show_max_min) {
      $(".form_field#minimum input[id$='_minimum']").val("");
      $(".form_field#minimum input[id$='_minstrictly']").prop("checked", false);
      $(".form_field#maximum input[id$='_maximum']").val("");
      $(".form_field#maximum input[id$='_maxstrictly']").prop("checked", false);
    }

    // show/hide key question
    var hide_key_q = (
      selected_type == "image" ||
      selected_type == "annotated_image" ||
      selected_type == "signature" ||
      selected_type == "sketch" ||
      selected_type == "audio" ||
      selected_type == "video"
    );
    $(".question_fields .question_key")[hide_key_q ? 'hide' : 'show']();

    // reset boxes if hiding
    if (hide_key_q) {
      $(".form_field#key input[id$='_key']").val("");
      $(".form_field#key input[id$='_key']").prop("checked", false);
    }
  }

  klass.prototype.show_option_set_select = function(show, options) { var self = this;
    var select = $("div.question_fields .form_field[data-field-name=option_set_id]");
    select[show ? 'show' : 'hide']();

    // If showing, disable the multilevel options based on options.multilevel.
    if (show) {
      var mult_options = select.find('.control select option[data-multilevel=true]');
      options.multilevel ? mult_options.removeAttr('disabled') : mult_options.attr('disabled', 'disabled');
    }

    // Reset value.
    if (!options.initial)
      select.find('.control select').val('');
  };

  // shows the create option set form and sets up a callback to receive the result
  klass.prototype.show_option_set_form = function() { var self = this;
    // show the loading indicator
    $('div.question_fields #option_set_id .loading_indicator').show();

    var question_type_param = '?adding_to_question_type=' + self.field_value('qtype_name'),
        loadUrl = self.params.new_option_set_path + question_type_param;

    var modal_header = "option_set.create_for_question";
    let question_code = $("#question_code").val().trim();
    if (question_code === "") {
      modal_header = "option_set.create_for_new_question";
    }
    $("#create-option-set .modal-title").html(I18n.t(modal_header, {code: question_code}));

    // populate and show the modal
    $("#create-option-set .modal-body.option-set").load(loadUrl, function(){
      $("#create-option-set").modal('show');
    });
  }

  // called when the option set is created so we can add it to the dropdown
  klass.prototype.option_set_created = function(option_set) { var self = this;
    // close the dialog
    $("#create-option-set").modal('hide');

    // add the new option set to the list and select it
    var option = $('<option>', {value: option_set.id, 'data-multilevel': option_set.multilevel}).text(option_set.name);
    $('div.question_fields .form_field#option_set_id select').append(option).val(option_set.id);

    // flash the option set row
    $('div.question_fields .form_field#option_set_id').effect("highlight", {}, 1000);
  };

}(ELMO.Views));
<commit_msg>5866: replace let with var which was causing an error in testing. Replace “ with ‘ for consistency.<commit_after>// ELMO.Views.QuestionForm
//
// View model for Question form
(function(ns, klass) {

  // constructor
  ns.QuestionForm = klass = function(params) { var self = this;
    self.params = params;

    // hookup type change event and trigger immediately
    var type_box = $('div.question_fields .form_field#qtype_name .control select');
    type_box.on('change', function(e){ self.question_type_changed(); });

    // run the type box changed event immediately
    // this might be the only time it runs since the form might be in show mode
    self.question_type_changed({initial: true});

    // hookup add option set link
    $('div.question_fields a.create_option_set').on('click', function(){ self.show_option_set_form(); return false; });

    // hookup form submit for modal
    $('#create-option-set .btn-primary').on('click', function() {$('form.option_set_form').submit();});

    // register a callback for when option set form submission is done
    $(document).on('option_set_form_submit_success', 'form.option_set_form', function(e, option_set){
      self.option_set_created(option_set);
    });
  };

  // gets the current value of the field with the given name
  // still works if field is read_only
  klass.prototype.field_value = function(field_name) { var self = this;
    var field_div = $('.question_fields .form_field[data-field-name=' + field_name + '] .control');

    // if read only
    if (field_div.is('.read_only')) {
      // first get the wrapper
      var wrapper = field_div.find('.ro-val');

      // now try to get the wrapper's data-val value, or just the wrapper's contents failing that
      return wrapper.data('val') || wrapper.text();

    // otherwise (not read only) just get the field value
    } else
      return field_div.find('input, select, textarea').val();
  }

  klass.prototype.question_type_changed = function(options) { var self = this;
    var selected_type = self.field_value('qtype_name');

    // Show/hide option set field and hint
    options = options || {};
    options.multilevel = selected_type == 'select_one';
    self.show_option_set_select(selected_type == 'select_one' || selected_type == 'select_multiple', options);

    // show/hide max/min
    var show_max_min = (selected_type == "decimal" || selected_type == "integer");
    $(".question_fields .minmax")[show_max_min ? 'show' : 'hide']();

    // reset boxes if hiding
    if (!show_max_min) {
      $(".form_field#minimum input[id$='_minimum']").val("");
      $(".form_field#minimum input[id$='_minstrictly']").prop("checked", false);
      $(".form_field#maximum input[id$='_maximum']").val("");
      $(".form_field#maximum input[id$='_maxstrictly']").prop("checked", false);
    }

    // show/hide key question
    var hide_key_q = (
      selected_type == "image" ||
      selected_type == "annotated_image" ||
      selected_type == "signature" ||
      selected_type == "sketch" ||
      selected_type == "audio" ||
      selected_type == "video"
    );
    $(".question_fields .question_key")[hide_key_q ? 'hide' : 'show']();

    // reset boxes if hiding
    if (hide_key_q) {
      $(".form_field#key input[id$='_key']").val("");
      $(".form_field#key input[id$='_key']").prop("checked", false);
    }
  }

  klass.prototype.show_option_set_select = function(show, options) { var self = this;
    var select = $("div.question_fields .form_field[data-field-name=option_set_id]");
    select[show ? 'show' : 'hide']();

    // If showing, disable the multilevel options based on options.multilevel.
    if (show) {
      var mult_options = select.find('.control select option[data-multilevel=true]');
      options.multilevel ? mult_options.removeAttr('disabled') : mult_options.attr('disabled', 'disabled');
    }

    // Reset value.
    if (!options.initial)
      select.find('.control select').val('');
  };

  // shows the create option set form and sets up a callback to receive the result
  klass.prototype.show_option_set_form = function() { var self = this;
    // show the loading indicator
    $('div.question_fields #option_set_id .loading_indicator').show();

    var question_type_param = '?adding_to_question_type=' + self.field_value('qtype_name'),
        loadUrl = self.params.new_option_set_path + question_type_param;

    var modal_header = 'option_set.create_for_question';
    var question_code = $('#question_code').val().trim();
    if (question_code === '') {
      modal_header = 'option_set.create_for_new_question';
    }
    $('#create-option-set .modal-title').html(I18n.t(modal_header, {code: question_code}));

    // populate and show the modal
    $('#create-option-set .modal-body.option-set').load(loadUrl, function(){
      $('#create-option-set').modal('show');
    });
  }

  // called when the option set is created so we can add it to the dropdown
  klass.prototype.option_set_created = function(option_set) { var self = this;
    // close the dialog
    $('#create-option-set').modal('hide');

    // add the new option set to the list and select it
    var option = $('<option>', {value: option_set.id, 'data-multilevel': option_set.multilevel}).text(option_set.name);
    $('div.question_fields .form_field#option_set_id select').append(option).val(option_set.id);

    // flash the option set row
    $('div.question_fields .form_field#option_set_id').effect("highlight", {}, 1000);
  };

}(ELMO.Views));
<|endoftext|>


<commit_before>// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require_tree .
<commit_msg>1, Improved the JavaScript Application manifest file.<commit_after>// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require_self
<|endoftext|>


<commit_before>/* ***********************************************************************************************

    Unify Project

    Homepage: unify-project.org
    License: MIT + Apache (V2)
    Copyright: 2009-2010 Deutsche Telekom AG, Germany, http://telekom.com

*********************************************************************************************** */
/* ************************************************************************

#asset(tweet/mobile/*)

************************************************************************ */

/**
 * Twitter application class for hero mobile devices.
 */
qx.Class.define("tweet.application.Mobile",
{
  extend : unify.application.Mobile,

  /*
  *****************************************************************************
     MEMBERS
  *****************************************************************************
  */

  members :
  {
    /*
    ---------------------------------------------------------------------------
      APPLICATION CORE
    ---------------------------------------------------------------------------
    */

    // overridden
    main : function()
    {
      // Call super class
      this.base(arguments);

      // Initialize Twitter business object
      var TwitterAuth = tweet.business.TwitterAuth.getInstance();
      TwitterAuth.setUser("telekomria");
      TwitterAuth.setPassword("32u8AH555wKdQvhqgZZ9");

      // Set up
      document.title = "Tweet";

      // Register views
      var ViewManager = unify.view.mobile.ViewManager.getInstance();
      ViewManager.add(tweet.view.mobile.Timeline);
      ViewManager.add(tweet.view.mobile.Status);
      ViewManager.add(tweet.view.mobile.Compose);
      ViewManager.add(tweet.view.mobile.Userlist);
      ViewManager.add(tweet.view.mobile.User);
      ViewManager.add(tweet.view.mobile.Search);

      // Configure tab bar
      var TabBar = unify.ui.mobile.TabBar.getInstance();
      TabBar.add(tweet.view.mobile.Timeline);
      TabBar.add(tweet.view.mobile.Userlist);
      TabBar.add(tweet.view.mobile.Search);

      // Initialize navigation
      unify.view.mobile.NavigationManager.getInstance().init();
    }
  }
});
<commit_msg>First step in convertion to new Unify tablet edition<commit_after>/* ***********************************************************************************************

    Unify Project

    Homepage: unify-project.org
    License: MIT + Apache (V2)
    Copyright: 2009-2010 Deutsche Telekom AG, Germany, http://telekom.com

*********************************************************************************************** */
/* ************************************************************************

#asset(tweet/mobile/*)

************************************************************************ */

/**
 * Twitter application class for hero mobile devices.
 */
qx.Class.define("tweet.application.Mobile",
{
  extend : unify.application.Mobile,

  /*
  *****************************************************************************
     MEMBERS
  *****************************************************************************
  */

  members :
  {
    /*
    ---------------------------------------------------------------------------
      APPLICATION CORE
    ---------------------------------------------------------------------------
    */

    // overridden
    main : function()
    {
      // Call super class
      this.base(arguments);

      // Initialize Twitter business object
      var TwitterAuth = tweet.business.TwitterAuth.getInstance();
      TwitterAuth.setUser("telekomria");
      TwitterAuth.setPassword("32u8AH555wKdQvhqgZZ9");

      // Set up
      document.title = "Tweet";

      var MasterViewManager = new unify.view.ViewManager("master");
      MasterViewManager.add(tweet.view.mobile.Timeline, true);
      MasterViewManager.add(tweet.view.mobile.Status);
      MasterViewManager.add(tweet.view.mobile.Compose);
      MasterViewManager.add(tweet.view.mobile.Userlist);
      MasterViewManager.add(tweet.view.mobile.User);
      MasterViewManager.add(tweet.view.mobile.Search);

      // Configure tab bar
      // var TabBar = unify.ui.mobile.TabBar.getInstance();
      // TabBar.add(tweet.view.mobile.Timeline);
      // TabBar.add(tweet.view.mobile.Userlist);
      // TabBar.add(tweet.view.mobile.Search);

      var Navigation = unify.view.Navigation.getInstance();
      Navigation.add(MasterViewManager);
      Navigation.add(DetailViewManager);
      Navigation.init();
    }
  }
});
<|endoftext|>


<commit_before>import Node from '../../pastel/node.js';
import Token from '../../pastel/token.js';
import CraftyBlock from '../CraftyBlock/CraftyBlock.js';
import CraftyBlockSpec from '../CraftyBlock/CraftyBlockSpec.js';
import CraftyStore from '../../stores/CraftyStore.js';
import crafty from './../../crafty/crafty.js';
import CraftyBlockMenu from './CraftyBlockMenu.js';
import CraftyBlockEvents from './CraftyBlockEvents.js';

/**
 * CraftyBlock Manager Class
 *
 * Manages existing and new blocks, and their positions
 *
 * @exports CraftyBlockManager
 */
export default class CraftyBlockManager {
    constructor(stage) {
        this.stage = stage;
        this.blocks = [];
        this.menu = new CraftyBlockMenu();

        //  Add Block Event Listeners
        CraftyBlockEvents.on('movingready', this.prepareBlockDrag.bind(this));
        CraftyBlockEvents.on('movingstart', this.startBlockDrag.bind(this));
        CraftyBlockEvents.on('movingend', this.endBlockDrag.bind(this));
        CraftyBlockEvents.on('createdonstage', (block) => {
            if (!this.rootBlocks.includes(block)) {
                this.rootBlocks.push(block);
                console.log(block);

                console.log("Block added to Stage! rootBlock.length = " + this.rootBlocks.length);
                this.checkBlockInfoList();
            }
        });
        CraftyBlockEvents.on('clickonce', (block) => {
            console.log("Clicked!");
            console.log(block);
            this.menu.toggle(block);
            this.stage.addChild(this.menu);
        });
        CraftyBlockEvents.on('deleteClicked', (block) => {
            this.removeBlock(block);
        });

        //  Load Saved Tree from CraftyStore
        this.loadTree();

        console.log("DEBUG::: Created CraftyBlockManager!");
    }

    prepareBlockDrag(block) {
        //  if block is in sidebar, create copy
        if (this.stage.sidebar.children.includes(block)) {
            let blockCopy = block.clone();
            this.stage.sidebar.addChildAt(blockCopy,1);
            block.render();
            block.createdFromSidebar = true;
        } else {
            block.createdFromSidebar = false;
        }
    }

    startBlockDrag(event) {
        let block = event.target;

        //console.log(event.data.getLocalPosition(this.stage));
        block.isClick = false;
        this.addToStage(block);

        //  TODO: Disable auto render for this case
    }

    endBlockDrag(event) {
        console.log("DEBUG::: Block drag ended!");

        let block = event.target;

        if (block.createdFromSidebar) {
            let relativeMousePosition = event.data.getLocalPosition(block.parent);
            if (this.stage.sidebar.containsPosition(relativeMousePosition)) {
                this.removeBlock(block);
            }
        }

        this.checkBlockInfoList();
    }

    /**
     * Loads saved tree from CraftyStore, blockifies trees, and positions the blocks
     */
    loadTree() {
        //  empty stage first
        this.emptyStage();

        let savedTree = CraftyStore.get('tree');

        let savedBlocks = this.blockify(savedTree);

        const MARGIN_LEFT = 70;
        const MARGIN_TOP = 150;
        const SPACING = 15;
        let blockPosition = MARGIN_TOP;

        //  Set position of blocks and add to stage
        savedBlocks.forEach( block => {
            block.position.x = MARGIN_LEFT;
            block.position.y = blockPosition;
            this.addToStage(block)
            blockPosition += block.height + SPACING;
        });

        console.log("DEBUG::: block-loading saved tree is done!");
    }

    /**
     * Delete all crafty blocks on stage
     */
    emptyStage() {
        //  iterate in reverse order
        for (let i=this.stage.children.length-1; i>=0;i--) {
            if (this.stage.getChildAt(i) instanceof CraftyBlock) {
                this.stage.removeChildAt(i);
            }
        }
    }

    /**
     * Removes a block out of existence
     */
    removeBlock(block) {
        if (block.parent instanceof CraftyBlock) {
            block.parent.removeChildBlock(block);
        }
        else if (this.stage.children.includes(block)) {
            this.stage.removeChild(block);
        }
    }

    /**
     * Add block to stage
     */
    addToStage(block) {
        console.log(`DEBUG::: Adding {${block.name}} to stage`);
        if (block.parent instanceof CraftyBlock) {
            block.parent.removeChildBlock(block);
        }

        this.stage.addChild(block);
    }

    /**
     * Transform Crafty block into pastel's parsed tree
     */
    treefy(blocks) {
        let tree;

        if (blocks instanceof Array) {
            tree = new Node();
            let childTrees = [];

            blocks.forEach( childBlock => {
                let childTree = this.treefy(childBlock)
                childTrees[childBlock.order] = childTree;
                //tree.addChild(childTree);
            });

            childTrees.forEach( childTree => {
                tree.addChild(childTree);
            });
        }
        else {
            let block = blocks;
            let token = new Token(Token.ID, block.name);
            if (block.type == CraftyBlock.FUNCTION) {
                tree = new Node();
                let subtree = new Node(token);

                tree.addChild(subtree);

                block.childBlocks.forEach( childBlock => {
                    tree.addChild(this.treefy(childBlock));
                });
            } else {
                tree = new Node(token);
            }
        }

        return tree;
    }

    /**
     * Transforms pastel's parsed tree from into Crafty blocks
     */
    blockify(node, index = 0) {
        //  for first try (whole stage), divide into groups and perform blockify on each subtree
        if (!node.parent) {
            //  for each children(subtree), map its blockified version
            //let blocks = node.children.map ( childNode => this.blockify(childNode) );
            let blocks = [];
            node.children.forEach( (childNode,index) => {
                let block = this.blockify(childNode);
                block.order = index;
                blocks.push(block);
            });

            return blocks;
        }
        else {
            //console.log("DEBUG::: blockifying...");
            if (!node.getData()) {
                let children = node.getChildren();
                let functionBlock;
                let childBlocks = [];
                children.forEach( (childNode, idx) => {
                    if (idx == 0) {
                        functionBlock = this.blockify(childNode, idx);
                    } else {
                        childBlocks.push(this.blockify(childNode, idx));
                    }
                });

                childBlocks.forEach( (block,index) => {
                    functionBlock.addChildBlock(block,index);
                });

                return functionBlock;
            }
            else {
                let blockInfo;
                if (index == 0) {
                    blockInfo = CraftyBlockSpec.functionWithName(node.getData().data);
                }
                else {
                    blockInfo = new CraftyBlockSpec(node.getData().data,CraftyBlock.CONSTANT);
                }
                return new CraftyBlock(blockInfo);
            }
        }
    }

    /**
     * DEPRECATED: use treefy
     *
     * Returns a string version of the selected block
    */
    stringify(block) {
        //  quick return space + letiable name or space + {parameter name}
        if (block.type == CraftyBlock.CONSTANT) {
            return " " + block.name;
        } else if (block.type == CraftyBlock.PARAMETER) {
            return " {" + block.name + "}";
        }

        let word = "";

        //  add starting parenthesis if the block is a function or in stage
        if (this.stage == block.parent) {
            word += "(";
        } else if (block.type == CraftyBlock.FUNCTION) {
            word += " (";
        }

        //  add block name
        word += block.name;

        //  add child blocks
        for (let i=0;i<block.parameters.length;i++) {
            if (block.childBlocks[i]) {
                word += this.stringify(block.childBlocks[i]);
            } else {
                word += this.stringify(block.parameterBlocks[i]);
            }
        }

        //  add closing parenthesis
        word += ")";

        return word;
    }

    checkBlockInfoList() {
        var numberOfBlocks = this.stage.children.length - 2;

        var i;
        var blockInfoList = new Array("");

        for (i = 1; i <= numberOfBlocks; i++) {
            blockInfoList[i-1] = this.stringify(this.stage.getChildAt(i+1));
        }

        //  call canvasChanged function
        crafty.canvasChanged(blockInfoList);
        // getBlockInfoList(BlockInfoList);
    }
}
<commit_msg>Manage root blocks with rootBlocks array<commit_after>import Node from '../../pastel/node.js';
import Token from '../../pastel/token.js';
import CraftyBlock from '../CraftyBlock/CraftyBlock.js';
import CraftyBlockSpec from '../CraftyBlock/CraftyBlockSpec.js';
import CraftyStore from '../../stores/CraftyStore.js';
import crafty from './../../crafty/crafty.js';
import CraftyBlockMenu from './CraftyBlockMenu.js';
import CraftyBlockEvents from './CraftyBlockEvents.js';

/**
 * CraftyBlock Manager Class
 *
 * Manages existing and new blocks, and their positions
 *
 * @exports CraftyBlockManager
 */
export default class CraftyBlockManager {
    constructor(stage) {
        this.stage = stage;
        this.rootBlocks = [];
        this.menu = new CraftyBlockMenu();

        //  Add Block Event Listeners
        CraftyBlockEvents.on('movingready', this.prepareBlockDrag.bind(this));
        CraftyBlockEvents.on('movingstart', this.startBlockDrag.bind(this));
        CraftyBlockEvents.on('movingend', this.endBlockDrag.bind(this));
        CraftyBlockEvents.on('createdonstage', (block) => {
            if (!this.rootBlocks.includes(block)) {
                this.rootBlocks.push(block);
                console.log(block);

                console.log("Block added to Stage! rootBlock.length = " + this.rootBlocks.length);
                this.checkBlockInfoList();
            }
        });
        CraftyBlockEvents.on('clickonce', (block) => {
            console.log("Clicked!");
            console.log(block);
            this.menu.toggle(block);
            this.stage.addChild(this.menu);
        });
        CraftyBlockEvents.on('deleteClicked', (block) => {
            this.removeBlock(block);
        });

        //  Load Saved Tree from CraftyStore
        this.loadTree();

        console.log("DEBUG::: Created CraftyBlockManager!");
    }

    prepareBlockDrag(block) {
        //  if block is in sidebar, create copy
        if (this.stage.sidebar.children.includes(block)) {
            let blockCopy = block.clone();
            this.stage.sidebar.addChildAt(blockCopy,1);
            block.render();
            block.createdFromSidebar = true;
        } else {
            block.createdFromSidebar = false;
        }
    }

    startBlockDrag(event) {
        let block = event.target;

        //console.log(event.data.getLocalPosition(this.stage));
        block.isClick = false;
        this.addToStage(block);

        //  TODO: Disable auto render for this case
    }

    endBlockDrag(event) {
        console.log("DEBUG::: Block drag ended!");

        let block = event.target;

        if (block.createdFromSidebar) {
            let relativeMousePosition = event.data.getLocalPosition(block.parent);
            if (this.stage.sidebar.containsPosition(relativeMousePosition)) {
                this.removeBlock(block);
            }
        }

        this.checkBlockInfoList();
    }

    /**
     * Loads saved tree from CraftyStore, blockifies trees, and positions the blocks
     */
    loadTree() {
        //  empty stage first
        this.emptyStage();

        let savedTree = CraftyStore.get('tree');

        this.rootBlocks = this.blockify(savedTree);

        const MARGIN_LEFT = 70;
        const MARGIN_TOP = 150;
        const SPACING = 15;
        let blockPosition = MARGIN_TOP;

        //  Set position of blocks and add to stage
        this.rootBlocks.forEach( block => {
            block.position.x = MARGIN_LEFT;
            block.position.y = blockPosition;
            this.addToStage(block)
            blockPosition += block.height + SPACING;
        });

        console.log("DEBUG::: block-loading saved tree is done!");
    }

    /**
     * Delete all crafty blocks on stage
     */
    emptyStage() {
        //  iterate in reverse order
        for (let i=this.rootBlocks.length-1; i>=0;i--) {
            this.removeBlock(this.rootBlocks[i]);
        }
    }

    /**
     * Removes a block out of existence
     */
    removeBlock(block) {
        if (block.parent instanceof CraftyBlock) {
            block.parent.removeChildBlock(block);
        } else {
            let index = this.rootBlocks.indexOf(block);
            if (index > -1) {
                this.rootBlocks.splice(index);
                this.stage.removeChild(block);
            }
        }
    }

    /**
     * Add block to stage
     */
    addToStage(block) {
        console.log(`DEBUG::: Adding {${block.name}} to stage`);
        if (block.parent instanceof CraftyBlock) {
            block.parent.removeChildBlock(block);
        }

        this.stage.addChild(block);
    }

    /**
     * Transform Crafty block into pastel's parsed tree
     */
    treefy(block) {
        let tree;

        let blockName = (block.type == CraftyBlock.PARAMETER) ? "{" + block.name + "}" : block.name;
        let token = new Token(Token.ID, blockName);

        if (block.type == CraftyBlock.FUNCTION) {
            tree = new Node();
            let subtree = new Node(token);

            tree.addChild(subtree);

            block.parameterBlocks.forEach( (parameterBlock, index) => {
                let childBlock = block.childBlocks[index];
                if (childBlock) {
                    tree.addChild(this.treefy(childBlock));
                } else {
                    tree.addChild(this.treefy(parameterBlock));
                }
            });
        } else {
            tree = new Node(token);
        }

        return tree;
    }

    /**
     * Transforms pastel's parsed tree from into Crafty blocks
     */
    blockify(node, index = 0) {
        //  for first try (whole stage), divide into groups and perform blockify on each subtree
        if (!node.parent) {
            //  for each children(subtree), map its blockified version
            //let blocks = node.children.map ( childNode => this.blockify(childNode) );
            let blocks = [];
            node.children.forEach( (childNode,index) => {
                let block = this.blockify(childNode);
                block.order = index;
                blocks.push(block);
            });

            return blocks;
        }
        else {
            //console.log("DEBUG::: blockifying...");
            if (!node.getData()) {
                let children = node.getChildren();
                let functionBlock;
                let childBlocks = [];
                children.forEach( (childNode, idx) => {
                    if (idx == 0) {
                        functionBlock = this.blockify(childNode, idx);
                    } else {
                        childBlocks.push(this.blockify(childNode, idx));
                    }
                });

                childBlocks.forEach( (block,index) => {
                    functionBlock.addChildBlock(block,index);
                });

                return functionBlock;
            }
            else {
                let blockInfo;
                if (index == 0) {
                    blockInfo = CraftyBlockSpec.functionWithName(node.getData().data);
                }
                else {
                    blockInfo = new CraftyBlockSpec(node.getData().data,CraftyBlock.CONSTANT);
                }
                return new CraftyBlock(blockInfo);
            }
        }
    }

    /**
     * DEPRECATED: use treefy
     *
     * Returns a string version of the selected block
    */
    stringify(block) {
        //  quick return space + letiable name or space + {parameter name}
        if (block.type == CraftyBlock.CONSTANT) {
            return " " + block.name;
        } else if (block.type == CraftyBlock.PARAMETER) {
            return " {" + block.name + "}";
        }

        let word = "";

        //  add starting parenthesis if the block is a function or in stage
        if (this.stage == block.parent) {
            word += "(";
        } else if (block.type == CraftyBlock.FUNCTION) {
            word += " (";
        }

        //  add block name
        word += block.name;

        //  add child blocks
        for (let i=0;i<block.parameters.length;i++) {
            if (block.childBlocks[i]) {
                word += this.stringify(block.childBlocks[i]);
            } else {
                word += this.stringify(block.parameterBlocks[i]);
            }
        }

        //  add closing parenthesis
        word += ")";

        return word;
    }

    checkBlockInfoList() {
        var numberOfBlocks = this.stage.children.length - 2;

        var i;
        var blockInfoList = new Array("");

        for (i = 1; i <= numberOfBlocks; i++) {
            blockInfoList[i-1] = this.stringify(this.stage.getChildAt(i+1));
        }

        //  call canvasChanged function
        crafty.canvasChanged(blockInfoList);
        // getBlockInfoList(BlockInfoList);
    }
}
<|endoftext|>


<commit_before>function ExtensionPanelBuilder() {}

window.InfinniUI.ExtensionPanelBuilder = ExtensionPanelBuilder;

_.inherit(ExtensionPanelBuilder, ContainerBuilder);

_.extend(ExtensionPanelBuilder.prototype, {

    applyMetadata: function (params) {
        var metadata = params.metadata;
        var element = params.element;
        var parentView = params.parentView;
        var builder = params.builder;

        ContainerBuilder.prototype.applyMetadata.call(this, params);

        element.setExtensionName(metadata['ExtensionName']);

        var parameters = {};
        _.each(metadata.Parameters, function (parameterMetadata) {
            var param = builder.buildType('Parameter', parameterMetadata, {parentView: parentView});
            parameters[param.getName()] = param;
        });

        element.setParameters(parameters);
        element.setContext(parentView.getContext());
        element.setBuilder(builder);
    },

    createElement: function (params) {
        var element = new ExtensionPanel(params.parent);

        return element;
    }
});
<commit_msg>fix parameter in extension panel builder<commit_after>function ExtensionPanelBuilder() {}

window.InfinniUI.ExtensionPanelBuilder = ExtensionPanelBuilder;

_.inherit(ExtensionPanelBuilder, ContainerBuilder);

_.extend(ExtensionPanelBuilder.prototype, {

    applyMetadata: function (params) {
        var metadata = params.metadata;
        var element = params.element;
        var parentView = params.parentView;
        var builder = params.builder;

        ContainerBuilder.prototype.applyMetadata.call(this, params);

        element.setExtensionName(metadata['ExtensionName']);

        var parameters = {};
        _.each(metadata.Parameters, function (parameterMetadata) {
            var param = builder.buildType('Parameter', parameterMetadata, {parentView: parentView, basePathOfProperty: params.basePathOfProperty});
            parameters[param.getName()] = param;
        });

        element.setParameters(parameters);
        element.setContext(parentView.getContext());
        element.setBuilder(builder);
    },

    createElement: function (params) {
        var element = new ExtensionPanel(params.parent);

        return element;
    }
});
<|endoftext|>


<commit_before>"use strict";

angular.module('arethusa.confEditor').directive('confAdder', function() {
  return {
    restrict: 'AE',
    scope: {
      text: '@',
      submitter: '&'
    },
    link: function(scope, element, attrs) {
      scope.submitInput = function() {
        scope.submitter({ input: scope.input });
        scope.input = '';
      };
    },
    templateUrl: 'templates/conf_editor/conf_adder.html'
  };
});
<commit_msg>Add a comment about behaviour of delegated fns<commit_after>"use strict";

angular.module('arethusa.confEditor').directive('confAdder', function() {
  return {
    restrict: 'AE',
    scope: {
      text: '@',
      submitter: '&'
    },
    link: function(scope, element, attrs) {
      scope.submitInput = function() {
        // Quite interesting how we need to pass the argument as
        // an object here... Can't really explain why atm.
        scope.submitter({ input: scope.input });
        scope.input = '';
      };
    },
    templateUrl: 'templates/conf_editor/conf_adder.html'
  };
});
<|endoftext|>


<commit_before>module.exports = {
  getIsRequired: function (displayName) { return `${displayName} is required` },
  getRadioQuestionIsRequired: function (displayName) { return `Select a ${displayName}` },
  getIsNumeric: function (displayName) { return `${displayName} must only contain numbers` },
  getDropboxIsRequired: function (displayName) { return `${displayName} is required` },
  getIsCurrency: function (displayName) { return `${displayName} must be a valid currency` },
  getIsGreaterThan: function (displayName) { return `${displayName} must be greater than zero` },
  getIsGreaterThanOrEqualTo: function (displayName) { return `${displayName} must be greater than or equal to zero` },
  isGreaterThanMinimumClaim: function (displayName) { return `${displayName} must be greater than one` },
  getAssistedDigitalCaseworkerSameClaim: 'You cannot process this claim since you filled it in on behalf of a visitor',
  getUploadTooLarge: 'File uploaded too large',
  getUploadIncorrectType: 'File uploaded was not an image or pdf',
  getUpdateConflict: function (currentStatus) { return `This record has been updated since you started viewing it, its current status is ${currentStatus}` },
  getIsLessThanMaximumDifferentApprovedAmount: function (displayName) { return `${displayName} can only be £250 or less` },
  getNonRejectedClaimExpenseResponse: function () { return 'At least one expense must not be rejected for the claim to be approved' },
  getBenefitCheckRequired: function () { return 'Decide if benefit check needed' },
  getPrisonerCheckRequired: function () { return 'Decide on prisoner check' },
  getExpenseCheckRequired: function () { return 'Decide on this expense' },
  getVisitConfirmationRequired: function () { return 'Decide on visit confirmation' },
  getAdditionalInformationRequired: function () { return 'More information needed' },
  getUserAssignmentConflict: function (user) { return `This claim has been assigned to ${user}` },
  getUserNotAssigned: function () { return 'You have not assigned yourself to this claim' },
  getIsValidFormat: function (displayName) { return `${displayName} must have valid format` },
  getIsLessThanLengthMessage: function (displayName, options) { return `${displayName} must be shorter than ${options.length} characters` }
}
<commit_msg>Updating message to £1<commit_after>module.exports = {
  getIsRequired: function (displayName) { return `${displayName} is required` },
  getRadioQuestionIsRequired: function (displayName) { return `Select a ${displayName}` },
  getIsNumeric: function (displayName) { return `${displayName} must only contain numbers` },
  getDropboxIsRequired: function (displayName) { return `${displayName} is required` },
  getIsCurrency: function (displayName) { return `${displayName} must be a valid currency` },
  getIsGreaterThan: function (displayName) { return `${displayName} must be greater than zero` },
  getIsGreaterThanOrEqualTo: function (displayName) { return `${displayName} must be greater than or equal to zero` },
  isGreaterThanMinimumClaim: function (displayName) { return `${displayName} must be greater than £1` },
  getAssistedDigitalCaseworkerSameClaim: 'You cannot process this claim since you filled it in on behalf of a visitor',
  getUploadTooLarge: 'File uploaded too large',
  getUploadIncorrectType: 'File uploaded was not an image or pdf',
  getUpdateConflict: function (currentStatus) { return `This record has been updated since you started viewing it, its current status is ${currentStatus}` },
  getIsLessThanMaximumDifferentApprovedAmount: function (displayName) { return `${displayName} can only be £250 or less` },
  getNonRejectedClaimExpenseResponse: function () { return 'At least one expense must not be rejected for the claim to be approved' },
  getBenefitCheckRequired: function () { return 'Decide if benefit check needed' },
  getPrisonerCheckRequired: function () { return 'Decide on prisoner check' },
  getExpenseCheckRequired: function () { return 'Decide on this expense' },
  getVisitConfirmationRequired: function () { return 'Decide on visit confirmation' },
  getAdditionalInformationRequired: function () { return 'More information needed' },
  getUserAssignmentConflict: function (user) { return `This claim has been assigned to ${user}` },
  getUserNotAssigned: function () { return 'You have not assigned yourself to this claim' },
  getIsValidFormat: function (displayName) { return `${displayName} must have valid format` },
  getIsLessThanLengthMessage: function (displayName, options) { return `${displayName} must be shorter than ${options.length} characters` }
}
<|endoftext|>


<commit_before>Template.SkillList.helpers({
	skills: Skills.find({
	}, {
		sort: {
			name: 1,
			attribute: 1
		}
	})
});

Template.SkillList.events({
	'click #add': function() {
		Router.go('skill.add');
	},
	'click #editSkill': function() {
		Router.go('skill.edit', {_id: this._id});
	}
})<commit_msg>Delete skill works.<commit_after>Template.SkillList.helpers({
	skills: Skills.find({
	}, {
		sort: {
			name: 1,
			attribute: 1
		}
	})
});

Template.SkillList.events({
	'click #add': function() {
		Router.go('skill.add');
	},
	'click #editSkill': function() {
		Router.go('skill.edit', {_id: this._id});
	},
	'click #deleteSkill': function() {
		Skills.remove( this._id);
		return false;
	}
})<|endoftext|>