Diagramming for ActiveX, V4.9.2 Beta

We are running beta tests on the new version of MindFusion ActiveX Flowchart Control. Below is a list of the new features and add-ons:

Resize table columns and rows
Columns and rows of a Table node can now be resized interactively if its AllowResizeColumns or AllowResizeRows properties are enabled. In order to resize, move the mouse pointer to the border line on column’s right side or row’s bottom side until it shows resize cursor and start dragging. The control raises TableColumnResized and TableRowResized events when the operation completes.

License keys
There is no separate trial build of the control’s libraries anymore. Instead, set the LicenseKey property to disable the component’s evaluation mode and stop displaying trial messages. License key strings are now listed on the Keys & Downloads page at MindFusion’s customer portal. Keys for MindFusion.Diagramming Pack will now work for ActiveX control too.

Miscellaneous

  • Table nodes can be roots of collapsible tree branches too. The Table class now provides Expandable and Expanded properties, and Expand and Collapse method. The control raises TableCollapsed and TableExpanded events when a table-rooted branch is collapsed or expanded.
  • SvgExporter.ExportString method returns a string containing the SVG markup;
  • fixed crash in integrated SvgExporter;

If you are interested in testing the beta version, please download this archive containing the control’s dll file:

https://mindfusion.eu/_beta/fcx492.zip

Technical support
MindFusion puts special effort in providing excellent customer support to all developers who use our components. You can write at the forum, help desk or use e-mail support@mindfusion.eu. All questions are usually answered within hours of being received.

About MindFusion.Diagramming for ActiveX: An ActiveX programming component that lets you create with ease every type of diagram, flowchart, scheme, chart, hierarchy, tree etc. The control supports rich user interaction model with advanced features like tool tips, grid alignment, docking points for nodes, scrolling and zooming and many more. FlowChartX implements 7 automatic layouts as well arrow routing. The appearance if each flowchart is completely customizable. Nodes can hold both images and text, their Z-order can be changed and there are tens of predefined shapes to choose from. Nodes support aero and glass visual effects.

The control also includes detailed documentation and many samples for a variety of languages and platforms. You can find more about the features of the tool at the features page or check the licensing scheme and the prices here.

Display Petri nets using MindFusion diagram component.

In this post we show how to build a Petri net using MindFusion.Diagramming for WinForms. Petri nets are used to model and study distributed systems. A net contains places, transitions and arcs. A place represents possible state of the system, and a transition represents the change from one state to another. Arcs connect places to transitions and show the flow direction.

First, create a new .NET Windows Forms project and add a Model.cs file to it where we’ll define Petri net model classes

public class Net
{
	public List Places { get; set; }
	public List Transitions { get; set; }
	public List Arcs { get; set; }

	public Net()
	{
		Places = new List();
		Transitions = new List();
		Arcs = new List();
	}
}

public class Node
{
	public string Label { get; set; }
}

public class Place : Node
{
	public int Tokens { get; set; }
}

public class Transition : Node
{
}

public class Arc
{
	// Arcs run from a place to a transition or vice versa,
	// never between places or between transitions.

	public Arc(Place input, Transition output)
	{
		Input = input;
		Output = output;
	}

	public Arc(Transition input, Place output)
	{
		Input = input;
		Output = output;
	}

	public Node Input { get; private set; }
	public Node Output { get; private set; }

	public int Multiplicity { get; set; }
}

Now we can create a simple Petri net:

Net CreateSampleNet()
{
	var net = new Net();

	var p1 = new Place { Label = "P1", Tokens = 1 };
	var p2 = new Place { Label = "P2", Tokens = 0 };
	var p3 = new Place { Label = "P3", Tokens = 2 };
	var p4 = new Place { Label = "P4", Tokens = 1 };

	net.Places.AddRange(new[] { p1, p2, p3, p4 });

	var t1 = new Transition { Label = "T1" };
	var t2 = new Transition { Label = "T2" };

	net.Transitions.AddRange(new[] { t1, t2 });

	var a1 = new Arc(p1, t1);
	var a2 = new Arc(t1, p2);
	var a3 = new Arc(t1, p3);
	var a4 = new Arc(p2, t2);
	var a5 = new Arc(p3, t2);
	var a6 = new Arc(t2, p4);
	var a7 = new Arc(t2, p1);

	net.Arcs.AddRange(new[] { a1, a2, a3, a4, a5, a6, a7 });

	return net;
}

Next, drop a DiagramView and Diagram objects on the form which we’ll use to visualize the net. Add the following method to create diagram elements representing the model objects, and run LayeredLayout to arrange them:

void BuildDiagram(Net net)
{
	var nodeMap = new Dictionary<node, diagramnode="">();

	var placeBounds = new RectangleF(0, 0, 16, 16);
	var transBounds = new RectangleF(0, 0, 6, 20);

	foreach (var place in net.Places)
	{
		var node = diagram.Factory.CreateShapeNode(placeBounds);
		node.Text = place.Label;
		node.TextFormat.LineAlignment = StringAlignment.Far;
		node.Shape = Shapes.Ellipse;
		node.Tag = place.Tokens;
		node.CustomDraw = CustomDraw.Additional;
		nodeMap[place] = node;
	}

	foreach (var trans in net.Transitions)
	{
		var node = diagram.Factory.CreateShapeNode(transBounds);
		node.Text = trans.Label;
		node.TextFormat.LineAlignment = StringAlignment.Far;
		node.Shape = Shapes.Rectangle;
		nodeMap[trans] = node;
	}

	foreach (var arc in net.Arcs)
	{
		var link = diagram.Factory.CreateDiagramLink(
			nodeMap[arc.Input], nodeMap[arc.Output]);
		link.Tag = arc.Multiplicity;
		link.HeadShape = ArrowHeads.PointerArrow;
	}

	var layout = new LayeredLayout();
	layout.Orientation = Orientation.Horizontal;
	layout.StraightenLongLinks = true;
	layout.Arrange(diagram);
}</node,>

We will use the DrawNode custom draw event to render marks associated with each place. Another possibility is to create a custom node class and override its Draw method.

void OnDrawNode(object sender, DrawNodeEventArgs e)
{
	var node = e.Node;
	var g = e.Graphics;

	if (node.Tag is int)
	{
		var tokens = (int)node.Tag;
		var cx = node.Bounds.Width / 2;
		var cy = node.Bounds.Height / 2;

		if (tokens == 1)
		{
			float r = cx / 2;
			DrawMark(cx, cy, r, g);
		}
		else if (tokens == 2)
		{
			float r = 2 * cx / 5;
			DrawMark(cx / 2, cy, r, g);
			DrawMark(3 * cx / 2, cy, r, g);
		}
		else if (tokens == 3)
		{
			float r = cx / 3;
			float y2 = 4 * cy / 3;
			DrawMark(cx, 2 * cy / 5, r, g);
			DrawMark(cx / 2, y2, r, g);
			DrawMark(3 * cx / 2, y2, r, g);
		}
	}
}

void DrawMark(float x, float y, float r, IGraphics g)
{
	g.FillEllipse(Brushes.Black, x - r, y - r, r * 2, r * 2);
}

Finally, set some appearance properties and call the methods above to build the diagram:

public MainForm()
{
	InitializeComponent();

	diagram.ShadowsStyle = ShadowsStyle.None;
	diagram.DiagramLinkStyle.Brush = new MindFusion.Drawing.SolidBrush(Color.Black);
	diagram.ShapeNodeStyle.Brush = new MindFusion.Drawing.SolidBrush(Color.White);
	diagram.ShapeNodeStyle.FontSize = 10f;
	diagram.ShapeNodeStyle.FontStyle = FontStyle.Bold;

	var textAbove = new[]
	{
		new LineTemplate(-100, -100, 200, -100),
		new LineTemplate(200, -100, 200, 0),
		new LineTemplate(200, 0, -100, 0),
		new LineTemplate(-100, 0, -100, -100)
	};
	Shapes.Ellipse.TextArea = textAbove;
	Shapes.Rectangle.TextArea = textAbove;

	var net = CreateSampleNet();
	BuildDiagram(net);
}

The final result is displayed below.
Petri net diagram

The complete sample project is available for download here:
PetriNet.zip

For more information on Petri nets, see this Wikipedia article:
http://en.wikipedia.org/wiki/Petri_net

All MindFusion.Diagramming libraries expose the same programming interface, so most of the sample code shown above will work with only a few modifications in WPF, ASP.NET, Silverlight and Java versions of the control.

Enjoy!

MindFusion Diagram Component for Xamarin Beta Version

MindFusion is pleased to announce the first release of its Diagramming component for Xamarin. The control is packed with a comprehensive set of features that allows programmers to create, modify and render various types of diagrams fast and easy.

Among its core features are table and container nodes, tree nodes, shape library with a rich choice of predefined node shapes, diagram links with various arrowhead styles and different connector types – Bezier, straight, polyline.

Each Xamarin diagram you build with the component is fully interactive – users can drag, move, resize, create and delete all types of nodes and links. The control fires events for the tiniest user gestures so your software can perform the necessary operations as a result. The event set includes every single action – from editing a link to deleting a node.

The chart’s appearance is fully customizable. Each element of the diagram exposes its complete set of style settings like brush, pen, font, which give you full control over its looks. You can apply glass and aero visual effects for glossier look.

You can organize content in layers for better visualization and use a grid for more precise location and alignment of diagram elements. Ready flowcharts can be quickly persisted into XML with the call of a single method.

We invite you to test the initial MindFusion Diagramming for Xamarin Release. Direct download is available from this link:

Download MindFusion Flowchart Component for Xamarin Beta Version

The download includes a sample project and detailed API reference.

Your questions, comments and feedback are welcomed. Use email support@mindfusion.eu or write at our discussion board. Either way we’ll be glad to receive and answer your feedback!

MindFusion Diagram control for Xamarin

MindFusion Diagram control for Xamarin

Create a musical score writer using MindFusion diagram component.

In this example we’ll show how to use various features of MindFusion.Diagramming API to create a musical score editor:

Custom node types
We’ll create a StaffNode class to represent the staff, and NoteNode class to represent a musical note.

Grouping
NoteNodes will be attached to the StaffNode they were dropped onto (or nearby). If users move the staff around, the notes from the group will follow it.

Custom drawing logic
We’ll show how to draw custom graphics by overriding DrawLocal method of base DiagramNode class.

Using SVG images
We’ll show how to load an SVG image (for the G clef) and draw it as part of staff graphics.

NodeListView control
NodeListView contains prototypical node instances whose clones are added to the diagram using drag-and-drop operations. We’ll add a staff and several notes to the list to let users drag them to the score diagram.

The completed sample project can be downloaded from this link:
ScoreWriter.zip

Let’s start by defining StaffNode class to draw staves in the score diagram, and implement its Draw methods to draw five lines:

public class StaffNode : DiagramNode
{
	public StaffNode()
	{
		var rect = Bounds;
		rect.Width = 200;
		SetBounds(rect, false, false);

		// disable vertical resize
		EnabledHandles =
			AdjustmentHandles.ResizeMiddleLeft |
			AdjustmentHandles.Move |
			AdjustmentHandles.ResizeMiddleRight;
	}

	public StaffNode(StaffNode prototype) : base(prototype)
	{
	}

	public override void DrawLocal(IGraphics graphics, RenderOptions options)
	{
		base.DrawLocal(graphics, options);

		for (int i = 0; i < 5; i++)
		{
			float y = i * Bounds.Height / 4;
			using (var pen = EffectivePen.CreateGdiPen())
				graphics.DrawLine(pen, 0, y, Bounds.Width, y);
		}
	}

	public override void DrawShadowLocal(IGraphics graphics, RenderOptions options)
	{
	}
}

Next, load an SVG drawing representing G clef and draw it at appropriate position. We’ll also override GetRepaintRect method to accommodate for parts of the clef that are drawn outside the staff’s boundaries:

static SvgContent gClef;

static StaffNode()
{
	gClef = new SvgContent();
	gClef.Parse("GClef.svg");
}

public override void DrawLocal(IGraphics graphics, RenderOptions options)
{
	// ...

	var rect = GetLocalBounds();
	rect.Inflate(0, 8);
	rect.X = 2;
	rect.Width = 14;
	gClef.Draw(graphics, rect);
}

public override RectangleF GetRepaintRect(bool includeConnected)
{
	var rect = base.GetRepaintRect(includeConnected);
	rect.Inflate(0, 8);
	return rect;
}

Create an initial StaffNode instance from Form.Load event:

var initialStaff = new StaffNode();
initialStaff.Move(10, 10);
diagram.Nodes.Add(initialStaff);

If you run the project now, you should see the following diagram:
score writer diagram in c#

Next, define the Duration enumeration and NoteNode class to represent musical notes of various durations:

enum Duration
{
	Whole,
	Half,
	Quarter,
	Eighth,
	Sixteenth
}

class NoteNode : DiagramNode
{
	public NoteNode()
	{
		Bounds = new RectangleF(0, 0, 6, 6);
		Duration = Duration.Whole;
	}

	public NoteNode(Duration duration)
	{
		Bounds = new RectangleF(0, 0, 6, 6);
		Duration = duration;
	}

	public Duration Duration { get; set; }

	int position = 0;
}

Implement NoteNode.Draw methods as follows:

public override void DrawLocal(IGraphics graphics, RenderOptions options)
{
	base.DrawLocal(graphics, options);

	var cx = Bounds.Width / 2;
	var cy = Bounds.Height / 2;

	var gs = graphics.Save();
	graphics.TranslateTransform(cx, cy);
	graphics.RotateTransform(-10);
	graphics.TranslateTransform(-cx, -cy);

	var bounds = GetLocalBounds();
	bounds.Inflate(0, -bounds.Width / 10);
	var path = new GraphicsPath();
	path.AddEllipse(bounds);

	if (Duration == Duration.Whole || Duration == Duration.Half)
	{
		bounds.Inflate(-bounds.Width / 8, -bounds.Width / 6);
		path.AddEllipse(bounds);
	}
	graphics.FillPath(Brushes.Black, path);

	graphics.Restore(gs);

	if (position < -1 || position > 8)
	{
		// draw ledger lines if above or below staff
		var pen = EffectivePen.CreateGdiPen();
		var staff = (StaffNode)MasterGroup.MainItem;
		var yoff = staff.Bounds.Y - Bounds.Y;
		int i1 = position < -1 ? position : 9;
		int i2 = position < -1 ? -2 : position;
		for (int i = i1; i <= i2; i++)
		{
			if (i % 2 != 0)
				continue;
			var y = yoff + i * staff.Bounds.Height / 8;
			graphics.DrawLine(pen, -2, y, Bounds.Width + 2, y);
		}
		pen.Dispose();
	}

	if (Duration != Duration.Whole)
	{
		// draw stem
		float x = Bounds.Width;
		float y = Bounds.Height / 2;
		var pen = new System.Drawing.Pen(Color.Black, 0.5f);
		graphics.DrawLine(pen,
				            x - pen.Width / 2, y,
				            x - pen.Width / 2, y - Bounds.Height * 2);
		pen.Dispose();
	}

	if (Duration == Duration.Eighth || Duration == Duration.Sixteenth)
	{
		DrawFlag(graphics,
				    bounds.Width,
				    bounds.Height / 2 - bounds.Height * 2,
				    bounds.Width + 1,
				    bounds.Height);
	}

	if (Duration == Duration.Sixteenth)
	{
		DrawFlag(graphics,
				    bounds.Width,
				    bounds.Height - bounds.Height * 2,
				    bounds.Width + 1,
				    bounds.Height);
	}
}

void DrawFlag(IGraphics graphics, float x, float y, float w, float h)
{
	float sh = h / 2;
	float sw = w / 3;

	var pen = new System.Drawing.Pen(Color.Black, 0.5f);
	x -= pen.Width / 2;
	graphics.DrawBezier(pen,
			            x, y,
			            x, y + sh,
			            x + sw * 1.2f, y + 2 * sh,
			            x + sw, y + 3 * sh);
	pen.Dispose();
}

public override void DrawShadowLocal(IGraphics graphics, RenderOptions options)
{
}

public override RectangleF GetRepaintRect(bool includeConnected)
{
	var r = Bounds;
	r.Y -= r.Height * 2;
	r.Height *= 3;
	r.Width *= 2;
	return r;
}

Now, drag a NodeListView to the form and populate it from Load handler:

nodeListView.AddNode(new StaffNode());

nodeListView.DefaultNodeSize = new SizeF(6, 6);
nodeListView.AddNode(new NoteNode(Duration.Whole));
nodeListView.AddNode(new NoteNode(Duration.Half));
nodeListView.AddNode(new NoteNode(Duration.Quarter));
nodeListView.AddNode(new NoteNode(Duration.Eighth));
nodeListView.AddNode(new NoteNode(Duration.Sixteenth));

Drag and drop will not work just yet. First, we must enable the DiagramView.AllowDrop property to accept drag-and-drop events. Next, the custom classes must implement a copy constructor and serialization methods to be able to instantiate them through OLE drag events:

public NoteNode(NoteNode prototype) : base(prototype)
{
	Duration = prototype.Duration;
}

protected override void SaveTo(System.IO.BinaryWriter writer, PersistContext context)
{
	base.SaveTo(writer, context);
	context.Writer.Write((int)Duration);
}

protected override void LoadFrom(System.IO.BinaryReader reader, PersistContext context)
{
	base.LoadFrom(reader, context);
	Duration = (Duration)context.Reader.ReadInt32();
}

As a final touch for this example, let’s implement aligning notes to staves’ lines and spaces. First lets declare a helper method that returns the nearest StaffNode at specified location in diagram:

static class DiagramExtensions
{
	static public StaffNode NearestStaff(this Diagram diagram, PointF point)
	{
		var staves = diagram.Nodes.OfType();

		StaffNode nearest = null;
		float minDist = float.MaxValue;

		foreach (var staff in staves)
		{
			if (staff.ContainsPoint(point))
				return staff;

			var borderPoint = staff.GetNearestBorderPoint(point);
			var dist = Utilities.Distance(borderPoint, point);
			if (dist < minDist)
			{
				minDist = dist;
				nearest = staff;
			}
		}

		return minDist < 20 ? nearest : null;
	}
}

Next, implement StaffNode.Align method that aligns its argument to a line or space in the staff:

public PointF Align(PointF point, out int position)
{
	// align to pitch line/space

	float h = Bounds.Height / 8;
	float offset = point.Y - Bounds.Y;
	position = (int)Math.Round(offset / h);
	offset = (float)Math.Round(offset / h) * h;
	point.Y = Bounds.Y + offset;
	return point;
}

Add NoteNode.AlignToStaff method that will find nearest StaffNode and align the note’s position to the staff.

public StaffNode AlignToStaff()
{
	position = 0;

	var staff = Parent.NearestStaff(GetCenter());
	if (staff == null)
		return null;

	var alignedPoint = staff.Align(GetCenter(), out position);
	alignedPoint.X -= Bounds.Width / 2;
	alignedPoint.Y -= Bounds.Height / 2;
	Move(alignedPoint.X, alignedPoint.Y);

	return staff;
}

We can align notes after drag-and-drop from NodeListView by handling diagram’s NodeCreated event. We’ll use the same handler to attach notes to that staff, so that if users move a StaffNode, its attached NoteNodes will follow.

private void OnNodeCreated(object sender, NodeEventArgs e)
{
	var note = e.Node as NoteNode;
	if (note != null)
	{
		var staff = note.AlignToStaff();
		if (staff != null)
			note.AttachTo(staff, AttachToNode.TopLeft);

		note.HandlesStyle = HandlesStyle.MoveOnly;
	}
}

Finally, override NoteNode.CompleteModify to align notes after user moves them to a different position on the staff or to another staff in the score:

protected override void CompleteModify(PointF end, InteractionState ist)
{
	base.CompleteModify(end, ist);

	var staff = AlignToStaff();
	if (staff != null)
		AttachTo(staff, AttachToNode.TopLeft);
	else
	{
		Detach();
	}
}

Let’s run the project and compose some music 🙂
.net diagram control

A fully-featured scorewriter software would also allow for drawing rest, sharp and flat symbols, C and F clefs, and some other musical notation features, but these are left as exercise to the reader 😉

The code above uses MindFusion’s .NET API and can be used with Windows Forms, WPF, Silverlight and ASP.NET diagramming components. The Java API for Android and desktop Swing application will look similar, with setter method calls instead of property assignments.

You can download the trial version of any MindFusion.Diagramming component from this page.

Enjoy!

WPF Diagram Control, V3.3.1 and WinForms Diagram Control, V6.3.3

MindFusion is pleased to announce the new releases of two of its popular flowchart control: Diagramming for WinForms, V6.3.3 and Diagramming for WPF, V3.3.1. Both releases have similar new features, which are listed below:

Resize table columns and rows
Columns and rows of a TableNode can now be resized interactively if its AllowResizeColumns or AllowResizeRows properties are enabled. In order to resize, move the mouse pointer to the border line on column’s right side or row’s bottom side until it shows resize cursor and start dragging. The control raises TableColumnResizing and TableRowResizing events to let you validate new size or prevent resizing some elements. The TableColumnResized and TableRowResized events are raised after the operation completes.

Barcode nodes
The BarcodeNode class displays EAN, UPC or QR barcodes as node’s content. In-place edit operations let users enter new numeric codes for 1D codes or text strings for QR codes. The barcode format is specified via the Format property, the encoded number or text is set via Content, and color of 1D bars / 2D modules via BarColor.

Barcode diagram nodes

Barcode diagram nodes

New Features in Diagramming for WPF, V3.3.1

ShapeDesigner improvements

  • The ShapeDesigner control supports undo. Call its Undo or Redo methods to respectively undo or redo a change done to the designed shape.
  • ZoomFactor property added to ShapeDesigner. It also supports interactive zoom in/out via mouse wheel.
  • The SelectedElement property exposes the graphic element currently selected in ShapeDesigner canvas. You can bind to its stroke and brush properties to create alternative user interface for editing element attributes.

Miscellaneous

  • NodeConstraints.KeepInsideDiagram prevents a node from leaving diagram boundaries during user interaction (the older RestrictItemsToBounds property does not stop nodes from leaving diagram area but returns them to original position if dropped outside).
  • dashed selection frames are now drawn in two colors and should be visible on both the default white background and custom darker backgrounds. You can change the second dash color via HandlesVisualStyle.DashBackground property.
  • set the WhileModifying flag in RoutingOptions.TriggerRerouting to reroute links while users drag their end points.
  • custom connection point classes can now override ConnectionPoint.NearestAnchorPoint to implement custom anchor point selection logic; the method is now also called at the beginning of interactive link creation.

New in Diagramming for WinForms, V6.3.3

Miscellaneous

  • the component now selects better end points for auto-routed links when using WhileCreating and WhileModifying routing modes;
  • custom connection point classes can now override ConnectionPoint.NearestAnchorPoint to implement custom anchor point selection logic; the method is now also called at the beginning of interactive link creation.
  • NodeConstraints.KeepInsideDiagram prevents a node from leaving diagram boundaries during user interaction (the older RestrictItemsToBounds property does not stop nodes from leaving diagram area but returns them to original position if dropped outside).
  • SvgNode supports SVG images with vector-effect=’non-scaling-stroke’ stroke attributes.
  • improved default Pen for dash-frame selection handles style. Dashed frames should now be visible on both the default white background and custom darker backgrounds.
  • ZoomControl can now be used with other components by MindFusion and has been moved to MindFusion.Common.WinForms assembly and namespace.

You are welcome to download the trial version for each control from the following links:

Diagramming for WinForms, V6.3.3 Trial Version Download

Diagramming for WPF, V3.3.1 Trial Version Download

If you have questions or run into problems using the components you can use the Diagramming components forum, the help desk or write us at support@mindfusion.eu. Our support team will be pleased to help you.

About MindFusion.Diagramming for WinForms: A programming component that provides any WinForms application with a full set of features for creating and customizing all types of diagrams, flowcharts, schemes, hierarchies, trees, graphs etc. The control provides numerous ways to save and load a diagram, six auxiliary controls and more than 10 automatic graph layout algorithms. Diagram elements include scrollable tables, container nodes, multi-segment arrows, custom diagram item types and many more. Further details here.

Diagramming for WinForms is a royalty-free component, clients get 12 month upgrade subscription when buying a license. The source code is also available for purchase. Visit the buy page for a list with the current license prices.

About MindFusion.Diagramming for Wpf: Designed and developed to be easy to integrate, use, and customize, this native WPF flowchart component places at your disposal every single feature you would ever need to create diagrams, graphs, schemes, org charts, DB relationships, genealogy trees, class hierarchies and many more. Its long list of style options gives you complete control over the appearance of the diagram. With a set of eight automatic layouts you are sure to find the arrangement that suits perfectly your WPF application.

The diagram control boasts a long list of events, properties and methods for user interaction, item creation, data input and output. You can read the full features list here. The online demo shows samples that demonstrate various capabilities of the control. The licensing scheme and prices are uploaded at the buy page. Source code is also available.